diff options
Diffstat (limited to 'net/core/rtnetlink.c')
| -rw-r--r-- | net/core/rtnetlink.c | 133 |
1 files changed, 107 insertions, 26 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 7ebed55b5f7d..666e0928ba40 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -818,7 +818,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, | |||
| 818 | nla_total_size(sizeof(struct ifla_vf_vlan)) + | 818 | nla_total_size(sizeof(struct ifla_vf_vlan)) + |
| 819 | nla_total_size(sizeof(struct ifla_vf_spoofchk)) + | 819 | nla_total_size(sizeof(struct ifla_vf_spoofchk)) + |
| 820 | nla_total_size(sizeof(struct ifla_vf_rate)) + | 820 | nla_total_size(sizeof(struct ifla_vf_rate)) + |
| 821 | nla_total_size(sizeof(struct ifla_vf_link_state))); | 821 | nla_total_size(sizeof(struct ifla_vf_link_state)) + |
| 822 | nla_total_size(sizeof(struct ifla_vf_rss_query_en))); | ||
| 822 | return size; | 823 | return size; |
| 823 | } else | 824 | } else |
| 824 | return 0; | 825 | return 0; |
| @@ -982,6 +983,24 @@ static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev) | |||
| 982 | return 0; | 983 | return 0; |
| 983 | } | 984 | } |
| 984 | 985 | ||
| 986 | static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev) | ||
| 987 | { | ||
| 988 | char name[IFNAMSIZ]; | ||
| 989 | int err; | ||
| 990 | |||
| 991 | err = dev_get_phys_port_name(dev, name, sizeof(name)); | ||
| 992 | if (err) { | ||
| 993 | if (err == -EOPNOTSUPP) | ||
| 994 | return 0; | ||
| 995 | return err; | ||
| 996 | } | ||
| 997 | |||
| 998 | if (nla_put(skb, IFLA_PHYS_PORT_NAME, strlen(name), name)) | ||
| 999 | return -EMSGSIZE; | ||
| 1000 | |||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 985 | static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev) | 1004 | static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev) |
| 986 | { | 1005 | { |
| 987 | int err; | 1006 | int err; |
| @@ -1037,8 +1056,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1037 | #ifdef CONFIG_RPS | 1056 | #ifdef CONFIG_RPS |
| 1038 | nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) || | 1057 | nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) || |
| 1039 | #endif | 1058 | #endif |
| 1040 | (dev->ifindex != dev->iflink && | 1059 | (dev->ifindex != dev_get_iflink(dev) && |
| 1041 | nla_put_u32(skb, IFLA_LINK, dev->iflink)) || | 1060 | nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))) || |
| 1042 | (upper_dev && | 1061 | (upper_dev && |
| 1043 | nla_put_u32(skb, IFLA_MASTER, upper_dev->ifindex)) || | 1062 | nla_put_u32(skb, IFLA_MASTER, upper_dev->ifindex)) || |
| 1044 | nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) || | 1063 | nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) || |
| @@ -1072,6 +1091,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1072 | if (rtnl_phys_port_id_fill(skb, dev)) | 1091 | if (rtnl_phys_port_id_fill(skb, dev)) |
| 1073 | goto nla_put_failure; | 1092 | goto nla_put_failure; |
| 1074 | 1093 | ||
| 1094 | if (rtnl_phys_port_name_fill(skb, dev)) | ||
| 1095 | goto nla_put_failure; | ||
| 1096 | |||
| 1075 | if (rtnl_phys_switch_id_fill(skb, dev)) | 1097 | if (rtnl_phys_switch_id_fill(skb, dev)) |
| 1076 | goto nla_put_failure; | 1098 | goto nla_put_failure; |
| 1077 | 1099 | ||
| @@ -1111,14 +1133,16 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1111 | struct ifla_vf_tx_rate vf_tx_rate; | 1133 | struct ifla_vf_tx_rate vf_tx_rate; |
| 1112 | struct ifla_vf_spoofchk vf_spoofchk; | 1134 | struct ifla_vf_spoofchk vf_spoofchk; |
| 1113 | struct ifla_vf_link_state vf_linkstate; | 1135 | struct ifla_vf_link_state vf_linkstate; |
| 1136 | struct ifla_vf_rss_query_en vf_rss_query_en; | ||
| 1114 | 1137 | ||
| 1115 | /* | 1138 | /* |
| 1116 | * Not all SR-IOV capable drivers support the | 1139 | * Not all SR-IOV capable drivers support the |
| 1117 | * spoofcheck query. Preset to -1 so the user | 1140 | * spoofcheck and "RSS query enable" query. Preset to |
| 1118 | * space tool can detect that the driver didn't | 1141 | * -1 so the user space tool can detect that the driver |
| 1119 | * report anything. | 1142 | * didn't report anything. |
| 1120 | */ | 1143 | */ |
| 1121 | ivi.spoofchk = -1; | 1144 | ivi.spoofchk = -1; |
| 1145 | ivi.rss_query_en = -1; | ||
| 1122 | memset(ivi.mac, 0, sizeof(ivi.mac)); | 1146 | memset(ivi.mac, 0, sizeof(ivi.mac)); |
| 1123 | /* The default value for VF link state is "auto" | 1147 | /* The default value for VF link state is "auto" |
| 1124 | * IFLA_VF_LINK_STATE_AUTO which equals zero | 1148 | * IFLA_VF_LINK_STATE_AUTO which equals zero |
| @@ -1131,7 +1155,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1131 | vf_rate.vf = | 1155 | vf_rate.vf = |
| 1132 | vf_tx_rate.vf = | 1156 | vf_tx_rate.vf = |
| 1133 | vf_spoofchk.vf = | 1157 | vf_spoofchk.vf = |
| 1134 | vf_linkstate.vf = ivi.vf; | 1158 | vf_linkstate.vf = |
| 1159 | vf_rss_query_en.vf = ivi.vf; | ||
| 1135 | 1160 | ||
| 1136 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); | 1161 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); |
| 1137 | vf_vlan.vlan = ivi.vlan; | 1162 | vf_vlan.vlan = ivi.vlan; |
| @@ -1141,6 +1166,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1141 | vf_rate.max_tx_rate = ivi.max_tx_rate; | 1166 | vf_rate.max_tx_rate = ivi.max_tx_rate; |
| 1142 | vf_spoofchk.setting = ivi.spoofchk; | 1167 | vf_spoofchk.setting = ivi.spoofchk; |
| 1143 | vf_linkstate.link_state = ivi.linkstate; | 1168 | vf_linkstate.link_state = ivi.linkstate; |
| 1169 | vf_rss_query_en.setting = ivi.rss_query_en; | ||
| 1144 | vf = nla_nest_start(skb, IFLA_VF_INFO); | 1170 | vf = nla_nest_start(skb, IFLA_VF_INFO); |
| 1145 | if (!vf) { | 1171 | if (!vf) { |
| 1146 | nla_nest_cancel(skb, vfinfo); | 1172 | nla_nest_cancel(skb, vfinfo); |
| @@ -1155,7 +1181,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1155 | nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), | 1181 | nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), |
| 1156 | &vf_spoofchk) || | 1182 | &vf_spoofchk) || |
| 1157 | nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate), | 1183 | nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate), |
| 1158 | &vf_linkstate)) | 1184 | &vf_linkstate) || |
| 1185 | nla_put(skb, IFLA_VF_RSS_QUERY_EN, | ||
| 1186 | sizeof(vf_rss_query_en), | ||
| 1187 | &vf_rss_query_en)) | ||
| 1159 | goto nla_put_failure; | 1188 | goto nla_put_failure; |
| 1160 | nla_nest_end(skb, vf); | 1189 | nla_nest_end(skb, vf); |
| 1161 | } | 1190 | } |
| @@ -1269,6 +1298,7 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { | |||
| 1269 | [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) }, | 1298 | [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) }, |
| 1270 | [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, | 1299 | [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, |
| 1271 | [IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) }, | 1300 | [IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) }, |
| 1301 | [IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) }, | ||
| 1272 | }; | 1302 | }; |
| 1273 | 1303 | ||
| 1274 | static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = { | 1304 | static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = { |
| @@ -1479,6 +1509,17 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) | |||
| 1479 | ivl->link_state); | 1509 | ivl->link_state); |
| 1480 | break; | 1510 | break; |
| 1481 | } | 1511 | } |
| 1512 | case IFLA_VF_RSS_QUERY_EN: { | ||
| 1513 | struct ifla_vf_rss_query_en *ivrssq_en; | ||
| 1514 | |||
| 1515 | ivrssq_en = nla_data(vf); | ||
| 1516 | err = -EOPNOTSUPP; | ||
| 1517 | if (ops->ndo_set_vf_rss_query_en) | ||
| 1518 | err = ops->ndo_set_vf_rss_query_en(dev, | ||
| 1519 | ivrssq_en->vf, | ||
| 1520 | ivrssq_en->setting); | ||
| 1521 | break; | ||
| 1522 | } | ||
| 1482 | default: | 1523 | default: |
| 1483 | err = -EINVAL; | 1524 | err = -EINVAL; |
| 1484 | break; | 1525 | break; |
| @@ -1815,6 +1856,42 @@ errout: | |||
| 1815 | return err; | 1856 | return err; |
| 1816 | } | 1857 | } |
| 1817 | 1858 | ||
| 1859 | static int rtnl_group_dellink(const struct net *net, int group) | ||
| 1860 | { | ||
| 1861 | struct net_device *dev, *aux; | ||
| 1862 | LIST_HEAD(list_kill); | ||
| 1863 | bool found = false; | ||
| 1864 | |||
| 1865 | if (!group) | ||
| 1866 | return -EPERM; | ||
| 1867 | |||
| 1868 | for_each_netdev(net, dev) { | ||
| 1869 | if (dev->group == group) { | ||
| 1870 | const struct rtnl_link_ops *ops; | ||
| 1871 | |||
| 1872 | found = true; | ||
| 1873 | ops = dev->rtnl_link_ops; | ||
| 1874 | if (!ops || !ops->dellink) | ||
| 1875 | return -EOPNOTSUPP; | ||
| 1876 | } | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | if (!found) | ||
| 1880 | return -ENODEV; | ||
| 1881 | |||
| 1882 | for_each_netdev_safe(net, dev, aux) { | ||
| 1883 | if (dev->group == group) { | ||
| 1884 | const struct rtnl_link_ops *ops; | ||
| 1885 | |||
| 1886 | ops = dev->rtnl_link_ops; | ||
| 1887 | ops->dellink(dev, &list_kill); | ||
| 1888 | } | ||
| 1889 | } | ||
| 1890 | unregister_netdevice_many(&list_kill); | ||
| 1891 | |||
| 1892 | return 0; | ||
| 1893 | } | ||
| 1894 | |||
| 1818 | static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) | 1895 | static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 1819 | { | 1896 | { |
| 1820 | struct net *net = sock_net(skb->sk); | 1897 | struct net *net = sock_net(skb->sk); |
| @@ -1838,6 +1915,8 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1838 | dev = __dev_get_by_index(net, ifm->ifi_index); | 1915 | dev = __dev_get_by_index(net, ifm->ifi_index); |
| 1839 | else if (tb[IFLA_IFNAME]) | 1916 | else if (tb[IFLA_IFNAME]) |
| 1840 | dev = __dev_get_by_name(net, ifname); | 1917 | dev = __dev_get_by_name(net, ifname); |
| 1918 | else if (tb[IFLA_GROUP]) | ||
| 1919 | return rtnl_group_dellink(net, nla_get_u32(tb[IFLA_GROUP])); | ||
| 1841 | else | 1920 | else |
| 1842 | return -EINVAL; | 1921 | return -EINVAL; |
| 1843 | 1922 | ||
| @@ -1873,7 +1952,7 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm) | |||
| 1873 | EXPORT_SYMBOL(rtnl_configure_link); | 1952 | EXPORT_SYMBOL(rtnl_configure_link); |
| 1874 | 1953 | ||
| 1875 | struct net_device *rtnl_create_link(struct net *net, | 1954 | struct net_device *rtnl_create_link(struct net *net, |
| 1876 | char *ifname, unsigned char name_assign_type, | 1955 | const char *ifname, unsigned char name_assign_type, |
| 1877 | const struct rtnl_link_ops *ops, struct nlattr *tb[]) | 1956 | const struct rtnl_link_ops *ops, struct nlattr *tb[]) |
| 1878 | { | 1957 | { |
| 1879 | int err; | 1958 | int err; |
| @@ -2345,7 +2424,7 @@ EXPORT_SYMBOL(rtmsg_ifinfo); | |||
| 2345 | 2424 | ||
| 2346 | static int nlmsg_populate_fdb_fill(struct sk_buff *skb, | 2425 | static int nlmsg_populate_fdb_fill(struct sk_buff *skb, |
| 2347 | struct net_device *dev, | 2426 | struct net_device *dev, |
| 2348 | u8 *addr, u32 pid, u32 seq, | 2427 | u8 *addr, u16 vid, u32 pid, u32 seq, |
| 2349 | int type, unsigned int flags, | 2428 | int type, unsigned int flags, |
| 2350 | int nlflags) | 2429 | int nlflags) |
| 2351 | { | 2430 | { |
| @@ -2367,6 +2446,9 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb, | |||
| 2367 | 2446 | ||
| 2368 | if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) | 2447 | if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) |
| 2369 | goto nla_put_failure; | 2448 | goto nla_put_failure; |
| 2449 | if (vid) | ||
| 2450 | if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid)) | ||
| 2451 | goto nla_put_failure; | ||
| 2370 | 2452 | ||
| 2371 | nlmsg_end(skb, nlh); | 2453 | nlmsg_end(skb, nlh); |
| 2372 | return 0; | 2454 | return 0; |
| @@ -2381,7 +2463,7 @@ static inline size_t rtnl_fdb_nlmsg_size(void) | |||
| 2381 | return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN); | 2463 | return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN); |
| 2382 | } | 2464 | } |
| 2383 | 2465 | ||
| 2384 | static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type) | 2466 | static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type) |
| 2385 | { | 2467 | { |
| 2386 | struct net *net = dev_net(dev); | 2468 | struct net *net = dev_net(dev); |
| 2387 | struct sk_buff *skb; | 2469 | struct sk_buff *skb; |
| @@ -2391,7 +2473,8 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type) | |||
| 2391 | if (!skb) | 2473 | if (!skb) |
| 2392 | goto errout; | 2474 | goto errout; |
| 2393 | 2475 | ||
| 2394 | err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF, 0); | 2476 | err = nlmsg_populate_fdb_fill(skb, dev, addr, vid, |
| 2477 | 0, 0, type, NTF_SELF, 0); | ||
| 2395 | if (err < 0) { | 2478 | if (err < 0) { |
| 2396 | kfree_skb(skb); | 2479 | kfree_skb(skb); |
| 2397 | goto errout; | 2480 | goto errout; |
| @@ -2526,7 +2609,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 2526 | nlh->nlmsg_flags); | 2609 | nlh->nlmsg_flags); |
| 2527 | 2610 | ||
| 2528 | if (!err) { | 2611 | if (!err) { |
| 2529 | rtnl_fdb_notify(dev, addr, RTM_NEWNEIGH); | 2612 | rtnl_fdb_notify(dev, addr, vid, RTM_NEWNEIGH); |
| 2530 | ndm->ndm_flags &= ~NTF_SELF; | 2613 | ndm->ndm_flags &= ~NTF_SELF; |
| 2531 | } | 2614 | } |
| 2532 | } | 2615 | } |
| @@ -2627,7 +2710,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 2627 | err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); | 2710 | err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); |
| 2628 | 2711 | ||
| 2629 | if (!err) { | 2712 | if (!err) { |
| 2630 | rtnl_fdb_notify(dev, addr, RTM_DELNEIGH); | 2713 | rtnl_fdb_notify(dev, addr, vid, RTM_DELNEIGH); |
| 2631 | ndm->ndm_flags &= ~NTF_SELF; | 2714 | ndm->ndm_flags &= ~NTF_SELF; |
| 2632 | } | 2715 | } |
| 2633 | } | 2716 | } |
| @@ -2652,7 +2735,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, | |||
| 2652 | if (*idx < cb->args[0]) | 2735 | if (*idx < cb->args[0]) |
| 2653 | goto skip; | 2736 | goto skip; |
| 2654 | 2737 | ||
| 2655 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, | 2738 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 0, |
| 2656 | portid, seq, | 2739 | portid, seq, |
| 2657 | RTM_NEWNEIGH, NTF_SELF, | 2740 | RTM_NEWNEIGH, NTF_SELF, |
| 2658 | NLM_F_MULTI); | 2741 | NLM_F_MULTI); |
| @@ -2695,7 +2778,6 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2695 | { | 2778 | { |
| 2696 | struct net_device *dev; | 2779 | struct net_device *dev; |
| 2697 | struct nlattr *tb[IFLA_MAX+1]; | 2780 | struct nlattr *tb[IFLA_MAX+1]; |
| 2698 | struct net_device *bdev = NULL; | ||
| 2699 | struct net_device *br_dev = NULL; | 2781 | struct net_device *br_dev = NULL; |
| 2700 | const struct net_device_ops *ops = NULL; | 2782 | const struct net_device_ops *ops = NULL; |
| 2701 | const struct net_device_ops *cops = NULL; | 2783 | const struct net_device_ops *cops = NULL; |
| @@ -2719,7 +2801,6 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2719 | return -ENODEV; | 2801 | return -ENODEV; |
| 2720 | 2802 | ||
| 2721 | ops = br_dev->netdev_ops; | 2803 | ops = br_dev->netdev_ops; |
| 2722 | bdev = br_dev; | ||
| 2723 | } | 2804 | } |
| 2724 | 2805 | ||
| 2725 | for_each_netdev(net, dev) { | 2806 | for_each_netdev(net, dev) { |
| @@ -2732,7 +2813,6 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2732 | cops = br_dev->netdev_ops; | 2813 | cops = br_dev->netdev_ops; |
| 2733 | } | 2814 | } |
| 2734 | 2815 | ||
| 2735 | bdev = dev; | ||
| 2736 | } else { | 2816 | } else { |
| 2737 | if (dev != br_dev && | 2817 | if (dev != br_dev && |
| 2738 | !(dev->priv_flags & IFF_BRIDGE_PORT)) | 2818 | !(dev->priv_flags & IFF_BRIDGE_PORT)) |
| @@ -2742,7 +2822,6 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2742 | !(dev->priv_flags & IFF_EBRIDGE)) | 2822 | !(dev->priv_flags & IFF_EBRIDGE)) |
| 2743 | continue; | 2823 | continue; |
| 2744 | 2824 | ||
| 2745 | bdev = br_dev; | ||
| 2746 | cops = ops; | 2825 | cops = ops; |
| 2747 | } | 2826 | } |
| 2748 | 2827 | ||
| @@ -2775,7 +2854,7 @@ static int brport_nla_put_flag(struct sk_buff *skb, u32 flags, u32 mask, | |||
| 2775 | 2854 | ||
| 2776 | int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | 2855 | int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, |
| 2777 | struct net_device *dev, u16 mode, | 2856 | struct net_device *dev, u16 mode, |
| 2778 | u32 flags, u32 mask) | 2857 | u32 flags, u32 mask, int nlflags) |
| 2779 | { | 2858 | { |
| 2780 | struct nlmsghdr *nlh; | 2859 | struct nlmsghdr *nlh; |
| 2781 | struct ifinfomsg *ifm; | 2860 | struct ifinfomsg *ifm; |
| @@ -2784,7 +2863,7 @@ int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | |||
| 2784 | u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; | 2863 | u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; |
| 2785 | struct net_device *br_dev = netdev_master_upper_dev_get(dev); | 2864 | struct net_device *br_dev = netdev_master_upper_dev_get(dev); |
| 2786 | 2865 | ||
| 2787 | nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), NLM_F_MULTI); | 2866 | nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), nlflags); |
| 2788 | if (nlh == NULL) | 2867 | if (nlh == NULL) |
| 2789 | return -EMSGSIZE; | 2868 | return -EMSGSIZE; |
| 2790 | 2869 | ||
| @@ -2804,8 +2883,8 @@ int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | |||
| 2804 | nla_put_u32(skb, IFLA_MASTER, br_dev->ifindex)) || | 2883 | nla_put_u32(skb, IFLA_MASTER, br_dev->ifindex)) || |
| 2805 | (dev->addr_len && | 2884 | (dev->addr_len && |
| 2806 | nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || | 2885 | nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || |
| 2807 | (dev->ifindex != dev->iflink && | 2886 | (dev->ifindex != dev_get_iflink(dev) && |
| 2808 | nla_put_u32(skb, IFLA_LINK, dev->iflink))) | 2887 | nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev)))) |
| 2809 | goto nla_put_failure; | 2888 | goto nla_put_failure; |
| 2810 | 2889 | ||
| 2811 | br_afspec = nla_nest_start(skb, IFLA_AF_SPEC); | 2890 | br_afspec = nla_nest_start(skb, IFLA_AF_SPEC); |
| @@ -2890,7 +2969,8 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2890 | if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { | 2969 | if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { |
| 2891 | if (idx >= cb->args[0] && | 2970 | if (idx >= cb->args[0] && |
| 2892 | br_dev->netdev_ops->ndo_bridge_getlink( | 2971 | br_dev->netdev_ops->ndo_bridge_getlink( |
| 2893 | skb, portid, seq, dev, filter_mask) < 0) | 2972 | skb, portid, seq, dev, filter_mask, |
| 2973 | NLM_F_MULTI) < 0) | ||
| 2894 | break; | 2974 | break; |
| 2895 | idx++; | 2975 | idx++; |
| 2896 | } | 2976 | } |
| @@ -2898,7 +2978,8 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2898 | if (ops->ndo_bridge_getlink) { | 2978 | if (ops->ndo_bridge_getlink) { |
| 2899 | if (idx >= cb->args[0] && | 2979 | if (idx >= cb->args[0] && |
| 2900 | ops->ndo_bridge_getlink(skb, portid, seq, dev, | 2980 | ops->ndo_bridge_getlink(skb, portid, seq, dev, |
| 2901 | filter_mask) < 0) | 2981 | filter_mask, |
| 2982 | NLM_F_MULTI) < 0) | ||
| 2902 | break; | 2983 | break; |
| 2903 | idx++; | 2984 | idx++; |
| 2904 | } | 2985 | } |
| @@ -2939,7 +3020,7 @@ static int rtnl_bridge_notify(struct net_device *dev) | |||
| 2939 | goto errout; | 3020 | goto errout; |
| 2940 | } | 3021 | } |
| 2941 | 3022 | ||
| 2942 | err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0); | 3023 | err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0, 0); |
| 2943 | if (err < 0) | 3024 | if (err < 0) |
| 2944 | goto errout; | 3025 | goto errout; |
| 2945 | 3026 | ||
