rtnetlink.c (ee2c25efdd46d7ed5605d6fe877bdf4b47a4ab2e) rtnetlink.c (090096bf3db1c281ddd034573260045888a68fea)
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * Routing netlink socket interface: protocol independent part.
7 *
8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>

--- 2034 unchanged lines hidden (view full) ---

2043 }
2044
2045 rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
2046 return;
2047errout:
2048 rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
2049}
2050
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * Routing netlink socket interface: protocol independent part.
7 *
8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>

--- 2034 unchanged lines hidden (view full) ---

2043 }
2044
2045 rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
2046 return;
2047errout:
2048 rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
2049}
2050
2051/**
2052 * ndo_dflt_fdb_add - default netdevice operation to add an FDB entry
2053 */
2054int ndo_dflt_fdb_add(struct ndmsg *ndm,
2055 struct nlattr *tb[],
2056 struct net_device *dev,
2057 const unsigned char *addr,
2058 u16 flags)
2059{
2060 int err = -EINVAL;
2061
2062 /* If aging addresses are supported device will need to
2063 * implement its own handler for this.
2064 */
2065 if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
2066 pr_info("%s: FDB only supports static addresses\n", dev->name);
2067 return err;
2068 }
2069
2070 if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
2071 err = dev_uc_add_excl(dev, addr);
2072 else if (is_multicast_ether_addr(addr))
2073 err = dev_mc_add_excl(dev, addr);
2074
2075 /* Only return duplicate errors if NLM_F_EXCL is set */
2076 if (err == -EEXIST && !(flags & NLM_F_EXCL))
2077 err = 0;
2078
2079 return err;
2080}
2081EXPORT_SYMBOL(ndo_dflt_fdb_add);
2082
2051static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2052{
2053 struct net *net = sock_net(skb->sk);
2054 struct ndmsg *ndm;
2055 struct nlattr *tb[NDA_MAX+1];
2056 struct net_device *dev;
2057 u8 *addr;
2058 int err;

--- 36 unchanged lines hidden (view full) ---

2095 err = ops->ndo_fdb_add(ndm, tb, dev, addr, nlh->nlmsg_flags);
2096 if (err)
2097 goto out;
2098 else
2099 ndm->ndm_flags &= ~NTF_MASTER;
2100 }
2101
2102 /* Embedded bridge, macvlan, and any other device support */
2083static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2084{
2085 struct net *net = sock_net(skb->sk);
2086 struct ndmsg *ndm;
2087 struct nlattr *tb[NDA_MAX+1];
2088 struct net_device *dev;
2089 u8 *addr;
2090 int err;

--- 36 unchanged lines hidden (view full) ---

2127 err = ops->ndo_fdb_add(ndm, tb, dev, addr, nlh->nlmsg_flags);
2128 if (err)
2129 goto out;
2130 else
2131 ndm->ndm_flags &= ~NTF_MASTER;
2132 }
2133
2134 /* Embedded bridge, macvlan, and any other device support */
2103 if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_add) {
2104 err = dev->netdev_ops->ndo_fdb_add(ndm, tb,
2105 dev, addr,
2106 nlh->nlmsg_flags);
2135 if ((ndm->ndm_flags & NTF_SELF)) {
2136 if (dev->netdev_ops->ndo_fdb_add)
2137 err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
2138 nlh->nlmsg_flags);
2139 else
2140 err = ndo_dflt_fdb_add(ndm, tb, dev, addr,
2141 nlh->nlmsg_flags);
2107
2108 if (!err) {
2109 rtnl_fdb_notify(dev, addr, RTM_NEWNEIGH);
2110 ndm->ndm_flags &= ~NTF_SELF;
2111 }
2112 }
2113out:
2114 return err;
2115}
2116
2142
2143 if (!err) {
2144 rtnl_fdb_notify(dev, addr, RTM_NEWNEIGH);
2145 ndm->ndm_flags &= ~NTF_SELF;
2146 }
2147 }
2148out:
2149 return err;
2150}
2151
2152/**
2153 * ndo_dflt_fdb_del - default netdevice operation to delete an FDB entry
2154 */
2155int ndo_dflt_fdb_del(struct ndmsg *ndm,
2156 struct nlattr *tb[],
2157 struct net_device *dev,
2158 const unsigned char *addr)
2159{
2160 int err = -EOPNOTSUPP;
2161
2162 /* If aging addresses are supported device will need to
2163 * implement its own handler for this.
2164 */
2165 if (ndm->ndm_state & NUD_PERMANENT) {
2166 pr_info("%s: FDB only supports static addresses\n", dev->name);
2167 return -EINVAL;
2168 }
2169
2170 if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
2171 err = dev_uc_del(dev, addr);
2172 else if (is_multicast_ether_addr(addr))
2173 err = dev_mc_del(dev, addr);
2174 else
2175 err = -EINVAL;
2176
2177 return err;
2178}
2179EXPORT_SYMBOL(ndo_dflt_fdb_del);
2180
2117static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2118{
2119 struct net *net = sock_net(skb->sk);
2120 struct ndmsg *ndm;
2121 struct nlattr *tb[NDA_MAX+1];
2122 struct net_device *dev;
2123 int err = -EINVAL;
2124 __u8 *addr;

--- 41 unchanged lines hidden (view full) ---

2166
2167 if (err)
2168 goto out;
2169 else
2170 ndm->ndm_flags &= ~NTF_MASTER;
2171 }
2172
2173 /* Embedded bridge, macvlan, and any other device support */
2181static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2182{
2183 struct net *net = sock_net(skb->sk);
2184 struct ndmsg *ndm;
2185 struct nlattr *tb[NDA_MAX+1];
2186 struct net_device *dev;
2187 int err = -EINVAL;
2188 __u8 *addr;

--- 41 unchanged lines hidden (view full) ---

2230
2231 if (err)
2232 goto out;
2233 else
2234 ndm->ndm_flags &= ~NTF_MASTER;
2235 }
2236
2237 /* Embedded bridge, macvlan, and any other device support */
2174 if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) {
2175 err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr);
2238 if (ndm->ndm_flags & NTF_SELF) {
2239 if (dev->netdev_ops->ndo_fdb_del)
2240 err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr);
2241 else
2242 err = ndo_dflt_fdb_del(ndm, tb, dev, addr);
2176
2177 if (!err) {
2178 rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);
2179 ndm->ndm_flags &= ~NTF_SELF;
2180 }
2181 }
2182out:
2183 return err;

--- 68 unchanged lines hidden (view full) ---

2252 br_dev = netdev_master_upper_dev_get(dev);
2253 ops = br_dev->netdev_ops;
2254 if (ops->ndo_fdb_dump)
2255 idx = ops->ndo_fdb_dump(skb, cb, dev, idx);
2256 }
2257
2258 if (dev->netdev_ops->ndo_fdb_dump)
2259 idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx);
2243
2244 if (!err) {
2245 rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);
2246 ndm->ndm_flags &= ~NTF_SELF;
2247 }
2248 }
2249out:
2250 return err;

--- 68 unchanged lines hidden (view full) ---

2319 br_dev = netdev_master_upper_dev_get(dev);
2320 ops = br_dev->netdev_ops;
2321 if (ops->ndo_fdb_dump)
2322 idx = ops->ndo_fdb_dump(skb, cb, dev, idx);
2323 }
2324
2325 if (dev->netdev_ops->ndo_fdb_dump)
2326 idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx);
2327 else
2328 ndo_dflt_fdb_dump(skb, cb, dev, idx);
2260 }
2261 rcu_read_unlock();
2262
2263 cb->args[0] = idx;
2264 return skb->len;
2265}
2266
2267int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,

--- 472 unchanged lines hidden ---
2329 }
2330 rcu_read_unlock();
2331
2332 cb->args[0] = idx;
2333 return skb->len;
2334}
2335
2336int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,

--- 472 unchanged lines hidden ---