]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
switchdev: pass pointer to fib_info instead of copy
authorJiri Pirko <jiri@mellanox.com>
Tue, 17 May 2016 16:58:08 +0000 (18:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Jun 2016 17:18:16 +0000 (10:18 -0700)
[ Upstream commit da4ed55165d41b1073f9a476f1c18493e9bf8c8e ]

The problem is that fib_info->nh is [0] so the struct fib_info
allocation size depends on number of nexthops. If we just copy fib_info,
we do not copy the nexthops info and driver accesses memory which is not
ours.

Given the fact that fib4 does not defer operations and therefore it does
not need copy, just pass the pointer down to drivers as it was done
before.

Fixes: 850d0cbc91 ("switchdev: remove pointers from switchdev objects")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/rocker/rocker.c
include/net/switchdev.h
net/switchdev/switchdev.c

index 2b34622a4bfe891be5d8f96609a5ec5b35d4bced..3920c3eb60061c16769792f820bed1965c7d9011 100644 (file)
@@ -4475,7 +4475,7 @@ static int rocker_port_obj_add(struct net_device *dev,
                fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
                err = rocker_port_fib_ipv4(rocker_port, trans,
                                           htonl(fib4->dst), fib4->dst_len,
-                                          &fib4->fi, fib4->tb_id, 0);
+                                          fib4->fi, fib4->tb_id, 0);
                break;
        case SWITCHDEV_OBJ_ID_PORT_FDB:
                err = rocker_port_fdb_add(rocker_port, trans,
@@ -4547,7 +4547,7 @@ static int rocker_port_obj_del(struct net_device *dev,
                fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
                err = rocker_port_fib_ipv4(rocker_port, NULL,
                                           htonl(fib4->dst), fib4->dst_len,
-                                          &fib4->fi, fib4->tb_id,
+                                          fib4->fi, fib4->tb_id,
                                           ROCKER_OP_FLAG_REMOVE);
                break;
        case SWITCHDEV_OBJ_ID_PORT_FDB:
index 1d22ce9f352e2e7610095c4b1774164aa6af4516..31d0e51438486e10e5634a71b5bdadbe142c69e7 100644 (file)
@@ -88,7 +88,7 @@ struct switchdev_obj_ipv4_fib {
        struct switchdev_obj obj;
        u32 dst;
        int dst_len;
-       struct fib_info fi;
+       struct fib_info *fi;
        u8 tos;
        u8 type;
        u32 nlflags;
index d5d7132ac847307ac076a9fd3320d1ea1425398d..1b58866175e625a1cf22c408e5afd6205e228117 100644 (file)
@@ -1169,6 +1169,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
                .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
                .dst = dst,
                .dst_len = dst_len,
+               .fi = fi,
                .tos = tos,
                .type = type,
                .nlflags = nlflags,
@@ -1177,8 +1178,6 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
        struct net_device *dev;
        int err = 0;
 
-       memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
-
        /* Don't offload route if using custom ip rules or if
         * IPv4 FIB offloading has been disabled completely.
         */
@@ -1222,6 +1221,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
                .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
                .dst = dst,
                .dst_len = dst_len,
+               .fi = fi,
                .tos = tos,
                .type = type,
                .nlflags = 0,
@@ -1230,8 +1230,6 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
        struct net_device *dev;
        int err = 0;
 
-       memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
-
        if (!(fi->fib_flags & RTNH_F_OFFLOAD))
                return 0;