aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Feldman <sfeldma@gmail.com>2015-03-09 16:59:09 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-09 23:56:52 -0400
commitf8f2147150de303e814c0452075d467734d3544b (patch)
tree96d28922f4b9d1643da9c50d0532652c3dc14167
parentbf0b211256be342e92d3ee5c5a1fb8d42f3928bb (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.c3
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--include/net/switchdev.h6
-rw-r--r--net/ipv4/fib_trie.c5
-rw-r--r--net/switchdev/switchdev.c7
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)
4152static int rocker_port_switch_fib_ipv4_add(struct net_device *dev, 4152static 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,
52int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev, 53int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev,
53 struct nlmsghdr *nlh, u16 flags); 54 struct nlmsghdr *nlh, u16 flags);
54int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, 55int 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);
56int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, 57int 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);
58void netdev_switch_fib_ipv4_abort(struct fib_info *fi); 59void 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
118static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, 119static 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 */
301int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, 303int 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 }