diff options
author | Scott Feldman <sfeldma@gmail.com> | 2015-03-09 16:59:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-09 23:56:52 -0400 |
commit | f8f2147150de303e814c0452075d467734d3544b (patch) | |
tree | 96d28922f4b9d1643da9c50d0532652c3dc14167 | |
parent | bf0b211256be342e92d3ee5c5a1fb8d42f3928bb (diff) |
switchdev: add netlink flags to IPv4 FIB add op
Pass in the netlink flags (NLM_F_*) into switchdev driver for IPv4 FIB add op
to allow driver to 1) optimize hardware updates, 2) handle ip route prepend
and append commands correctly.
Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Suggested-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/rocker/rocker.c | 3 | ||||
-rw-r--r-- | include/linux/netdevice.h | 3 | ||||
-rw-r--r-- | include/net/switchdev.h | 6 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 5 | ||||
-rw-r--r-- | net/switchdev/switchdev.c | 7 |
5 files changed, 17 insertions, 7 deletions
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index 65e140315a58..223348d8cc07 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c | |||
@@ -4152,7 +4152,8 @@ static int rocker_port_switch_port_stp_update(struct net_device *dev, u8 state) | |||
4152 | static int rocker_port_switch_fib_ipv4_add(struct net_device *dev, | 4152 | static int rocker_port_switch_fib_ipv4_add(struct net_device *dev, |
4153 | __be32 dst, int dst_len, | 4153 | __be32 dst, int dst_len, |
4154 | struct fib_info *fi, | 4154 | struct fib_info *fi, |
4155 | u8 tos, u8 type, u32 tb_id) | 4155 | u8 tos, u8 type, |
4156 | u32 nlflags, u32 tb_id) | ||
4156 | { | 4157 | { |
4157 | struct rocker_port *rocker_port = netdev_priv(dev); | 4158 | struct rocker_port *rocker_port = netdev_priv(dev); |
4158 | int flags = 0; | 4159 | int flags = 0; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 45413784a3b1..1354ae83efc8 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1035,7 +1035,7 @@ struct fib_info; | |||
1035 | * state change. | 1035 | * state change. |
1036 | * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst, | 1036 | * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst, |
1037 | * int dst_len, struct fib_info *fi, | 1037 | * int dst_len, struct fib_info *fi, |
1038 | * u8 tos, u8 type, u32 tb_id); | 1038 | * u8 tos, u8 type, u32 nlflags, u32 tb_id); |
1039 | * Called to add/modify IPv4 route to switch device. | 1039 | * Called to add/modify IPv4 route to switch device. |
1040 | * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst, | 1040 | * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst, |
1041 | * int dst_len, struct fib_info *fi, | 1041 | * int dst_len, struct fib_info *fi, |
@@ -1207,6 +1207,7 @@ struct net_device_ops { | |||
1207 | int dst_len, | 1207 | int dst_len, |
1208 | struct fib_info *fi, | 1208 | struct fib_info *fi, |
1209 | u8 tos, u8 type, | 1209 | u8 tos, u8 type, |
1210 | u32 nlflags, | ||
1210 | u32 tb_id); | 1211 | u32 tb_id); |
1211 | int (*ndo_switch_fib_ipv4_del)(struct net_device *dev, | 1212 | int (*ndo_switch_fib_ipv4_del)(struct net_device *dev, |
1212 | __be32 dst, | 1213 | __be32 dst, |
diff --git a/include/net/switchdev.h b/include/net/switchdev.h index 933fac410a7a..1a9382febcc3 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * include/net/switchdev.h - Switch device API | 2 | * include/net/switchdev.h - Switch device API |
3 | * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> | 3 | * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> |
4 | * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com> | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -52,7 +53,7 @@ int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev, | |||
52 | int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev, | 53 | int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev, |
53 | struct nlmsghdr *nlh, u16 flags); | 54 | struct nlmsghdr *nlh, u16 flags); |
54 | int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, | 55 | int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, |
55 | u8 tos, u8 type, u32 tb_id); | 56 | u8 tos, u8 type, u32 nlflags, u32 tb_id); |
56 | int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, | 57 | int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, |
57 | u8 tos, u8 type, u32 tb_id); | 58 | u8 tos, u8 type, u32 tb_id); |
58 | void netdev_switch_fib_ipv4_abort(struct fib_info *fi); | 59 | void netdev_switch_fib_ipv4_abort(struct fib_info *fi); |
@@ -117,7 +118,8 @@ static inline int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device * | |||
117 | 118 | ||
118 | static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, | 119 | static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, |
119 | struct fib_info *fi, | 120 | struct fib_info *fi, |
120 | u8 tos, u8 type, u32 tb_id) | 121 | u8 tos, u8 type, |
122 | u32 nlflags, u32 tb_id) | ||
121 | { | 123 | { |
122 | return 0; | 124 | return 0; |
123 | } | 125 | } |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 90955455884e..fcfa9825a816 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1155,6 +1155,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1155 | err = netdev_switch_fib_ipv4_add(key, plen, fi, | 1155 | err = netdev_switch_fib_ipv4_add(key, plen, fi, |
1156 | new_fa->fa_tos, | 1156 | new_fa->fa_tos, |
1157 | cfg->fc_type, | 1157 | cfg->fc_type, |
1158 | cfg->fc_nlflags, | ||
1158 | tb->tb_id); | 1159 | tb->tb_id); |
1159 | if (err) { | 1160 | if (err) { |
1160 | netdev_switch_fib_ipv4_abort(fi); | 1161 | netdev_switch_fib_ipv4_abort(fi); |
@@ -1201,7 +1202,9 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1201 | 1202 | ||
1202 | /* (Optionally) offload fib entry to switch hardware. */ | 1203 | /* (Optionally) offload fib entry to switch hardware. */ |
1203 | err = netdev_switch_fib_ipv4_add(key, plen, fi, tos, | 1204 | err = netdev_switch_fib_ipv4_add(key, plen, fi, tos, |
1204 | cfg->fc_type, tb->tb_id); | 1205 | cfg->fc_type, |
1206 | cfg->fc_nlflags, | ||
1207 | tb->tb_id); | ||
1205 | if (err) { | 1208 | if (err) { |
1206 | netdev_switch_fib_ipv4_abort(fi); | 1209 | netdev_switch_fib_ipv4_abort(fi); |
1207 | goto out_free_new_fa; | 1210 | goto out_free_new_fa; |
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index aba6aa2656d8..8cf42a69baf4 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/switchdev/switchdev.c - Switch device API | 2 | * net/switchdev/switchdev.c - Switch device API |
3 | * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> | 3 | * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> |
4 | * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com> | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -294,12 +295,13 @@ static struct net_device *netdev_switch_get_dev_by_nhs(struct fib_info *fi) | |||
294 | * @fi: route FIB info structure | 295 | * @fi: route FIB info structure |
295 | * @tos: route TOS | 296 | * @tos: route TOS |
296 | * @type: route type | 297 | * @type: route type |
298 | * @nlflags: netlink flags passed in (NLM_F_*) | ||
297 | * @tb_id: route table ID | 299 | * @tb_id: route table ID |
298 | * | 300 | * |
299 | * Add IPv4 route entry to switch device. | 301 | * Add IPv4 route entry to switch device. |
300 | */ | 302 | */ |
301 | int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, | 303 | int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, |
302 | u8 tos, u8 type, u32 tb_id) | 304 | u8 tos, u8 type, u32 nlflags, u32 tb_id) |
303 | { | 305 | { |
304 | struct net_device *dev; | 306 | struct net_device *dev; |
305 | const struct net_device_ops *ops; | 307 | const struct net_device_ops *ops; |
@@ -324,7 +326,8 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, | |||
324 | 326 | ||
325 | if (ops->ndo_switch_fib_ipv4_add) { | 327 | if (ops->ndo_switch_fib_ipv4_add) { |
326 | err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len, | 328 | err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len, |
327 | fi, tos, type, tb_id); | 329 | fi, tos, type, nlflags, |
330 | tb_id); | ||
328 | if (!err) | 331 | if (!err) |
329 | fi->fib_flags |= RTNH_F_EXTERNAL; | 332 | fi->fib_flags |= RTNH_F_EXTERNAL; |
330 | } | 333 | } |