@@ -2048,6 +2048,38 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type)
2048
2048
rtnl_set_sk_err (net , RTNLGRP_NEIGH , err );
2049
2049
}
2050
2050
2051
+ /**
2052
+ * ndo_dflt_fdb_add - default netdevice operation to add an FDB entry
2053
+ */
2054
+ int 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
+ }
2081
+ EXPORT_SYMBOL (ndo_dflt_fdb_add );
2082
+
2051
2083
static int rtnl_fdb_add (struct sk_buff * skb , struct nlmsghdr * nlh , void * arg )
2052
2084
{
2053
2085
struct net * net = sock_net (skb -> sk );
@@ -2100,10 +2132,13 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2100
2132
}
2101
2133
2102
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
2142
2108
2143
if (!err ) {
2109
2144
rtnl_fdb_notify (dev , addr , RTM_NEWNEIGH );
@@ -2114,6 +2149,35 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2114
2149
return err ;
2115
2150
}
2116
2151
2152
+ /**
2153
+ * ndo_dflt_fdb_del - default netdevice operation to delete an FDB entry
2154
+ */
2155
+ int 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
+ }
2179
+ EXPORT_SYMBOL (ndo_dflt_fdb_del );
2180
+
2117
2181
static int rtnl_fdb_del (struct sk_buff * skb , struct nlmsghdr * nlh , void * arg )
2118
2182
{
2119
2183
struct net * net = sock_net (skb -> sk );
@@ -2171,8 +2235,11 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2171
2235
}
2172
2236
2173
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
2243
2177
2244
if (!err ) {
2178
2245
rtnl_fdb_notify (dev , addr , RTM_DELNEIGH );
@@ -2257,6 +2324,8 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
2257
2324
2258
2325
if (dev -> netdev_ops -> ndo_fdb_dump )
2259
2326
idx = dev -> netdev_ops -> ndo_fdb_dump (skb , cb , dev , idx );
2327
+ else
2328
+ ndo_dflt_fdb_dump (skb , cb , dev , idx );
2260
2329
}
2261
2330
rcu_read_unlock ();
2262
2331
0 commit comments