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 | } |
