@@ -1643,13 +1643,124 @@ static int br_vlan_rtm_dump(struct sk_buff *skb, struct netlink_callback *cb)
1643
1643
return err ;
1644
1644
}
1645
1645
1646
+ static const struct nla_policy br_vlan_db_policy [BRIDGE_VLANDB_ENTRY_MAX + 1 ] = {
1647
+ [BRIDGE_VLANDB_ENTRY_INFO ] = { .type = NLA_EXACT_LEN ,
1648
+ .len = sizeof (struct bridge_vlan_info ) },
1649
+ };
1650
+
1651
+ static int br_vlan_rtm_process_one (struct net_device * dev ,
1652
+ const struct nlattr * attr ,
1653
+ int cmd , struct netlink_ext_ack * extack )
1654
+ {
1655
+ struct bridge_vlan_info * vinfo , * vinfo_last = NULL ;
1656
+ struct nlattr * tb [BRIDGE_VLANDB_ENTRY_MAX + 1 ];
1657
+ struct net_bridge_vlan_group * vg ;
1658
+ struct net_bridge_port * p = NULL ;
1659
+ int err = 0 , cmdmap = 0 ;
1660
+ struct net_bridge * br ;
1661
+ bool changed = false;
1662
+
1663
+ if (netif_is_bridge_master (dev )) {
1664
+ br = netdev_priv (dev );
1665
+ vg = br_vlan_group (br );
1666
+ } else {
1667
+ p = br_port_get_rtnl (dev );
1668
+ if (WARN_ON (!p ))
1669
+ return - ENODEV ;
1670
+ br = p -> br ;
1671
+ vg = nbp_vlan_group (p );
1672
+ }
1673
+
1674
+ if (WARN_ON (!vg ))
1675
+ return - ENODEV ;
1676
+
1677
+ err = nla_parse_nested (tb , BRIDGE_VLANDB_ENTRY_MAX , attr ,
1678
+ br_vlan_db_policy , extack );
1679
+ if (err )
1680
+ return err ;
1681
+
1682
+ if (!tb [BRIDGE_VLANDB_ENTRY_INFO ]) {
1683
+ NL_SET_ERR_MSG_MOD (extack , "Missing vlan entry info" );
1684
+ return - EINVAL ;
1685
+ }
1686
+
1687
+ vinfo = nla_data (tb [BRIDGE_VLANDB_ENTRY_INFO ]);
1688
+ if (vinfo -> flags & (BRIDGE_VLAN_INFO_RANGE_BEGIN |
1689
+ BRIDGE_VLAN_INFO_RANGE_END )) {
1690
+ NL_SET_ERR_MSG_MOD (extack , "Old-style vlan ranges are not allowed when using RTM vlan calls" );
1691
+ return - EINVAL ;
1692
+ }
1693
+ if (!br_vlan_valid_id (vinfo -> vid , extack ))
1694
+ return - EINVAL ;
1695
+
1696
+ switch (cmd ) {
1697
+ case RTM_NEWVLAN :
1698
+ cmdmap = RTM_SETLINK ;
1699
+ break ;
1700
+ }
1701
+
1702
+ err = br_process_vlan_info (br , p , cmdmap , vinfo , & vinfo_last , & changed ,
1703
+ extack );
1704
+ if (changed )
1705
+ br_ifinfo_notify (cmdmap , br , p );
1706
+
1707
+ return err ;
1708
+ }
1709
+
1710
+ static int br_vlan_rtm_process (struct sk_buff * skb , struct nlmsghdr * nlh ,
1711
+ struct netlink_ext_ack * extack )
1712
+ {
1713
+ struct net * net = sock_net (skb -> sk );
1714
+ struct br_vlan_msg * bvm ;
1715
+ struct net_device * dev ;
1716
+ struct nlattr * attr ;
1717
+ int err , vlans = 0 ;
1718
+ int rem ;
1719
+
1720
+ /* this should validate the header and check for remaining bytes */
1721
+ err = nlmsg_parse (nlh , sizeof (* bvm ), NULL , BRIDGE_VLANDB_MAX , NULL ,
1722
+ extack );
1723
+ if (err < 0 )
1724
+ return err ;
1725
+
1726
+ bvm = nlmsg_data (nlh );
1727
+ dev = __dev_get_by_index (net , bvm -> ifindex );
1728
+ if (!dev )
1729
+ return - ENODEV ;
1730
+
1731
+ if (!netif_is_bridge_master (dev ) && !netif_is_bridge_port (dev )) {
1732
+ NL_SET_ERR_MSG_MOD (extack , "The device is not a valid bridge or bridge port" );
1733
+ return - EINVAL ;
1734
+ }
1735
+
1736
+ nlmsg_for_each_attr (attr , nlh , sizeof (* bvm ), rem ) {
1737
+ if (nla_type (attr ) != BRIDGE_VLANDB_ENTRY )
1738
+ continue ;
1739
+
1740
+ vlans ++ ;
1741
+ err = br_vlan_rtm_process_one (dev , attr , nlh -> nlmsg_type ,
1742
+ extack );
1743
+ if (err )
1744
+ break ;
1745
+ }
1746
+ if (!vlans ) {
1747
+ NL_SET_ERR_MSG_MOD (extack , "No vlans found to process" );
1748
+ err = - EINVAL ;
1749
+ }
1750
+
1751
+ return err ;
1752
+ }
1753
+
1646
1754
void br_vlan_rtnl_init (void )
1647
1755
{
1648
1756
rtnl_register_module (THIS_MODULE , PF_BRIDGE , RTM_GETVLAN , NULL ,
1649
1757
br_vlan_rtm_dump , 0 );
1758
+ rtnl_register_module (THIS_MODULE , PF_BRIDGE , RTM_NEWVLAN ,
1759
+ br_vlan_rtm_process , NULL , 0 );
1650
1760
}
1651
1761
1652
1762
void br_vlan_rtnl_uninit (void )
1653
1763
{
1654
1764
rtnl_unregister (PF_BRIDGE , RTM_GETVLAN );
1765
+ rtnl_unregister (PF_BRIDGE , RTM_NEWVLAN );
1655
1766
}
0 commit comments