Skip to content

Commit 86872cb

Browse files
tgrafDavid S. Miller
authored andcommitted
[IPv6] route: FIB6 configuration using struct fib6_config
Replaces the struct in6_rtmsg based interface orignating from the ioctl interface with a struct fib6_config based on. Allows changing the interface without breaking the ioctl interface and avoids passing on tons of parameters. The recently introduced struct nl_info is used to pass on netlink authorship information for notifications. Signed-off-by: Thomas Graf <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 40e22e8 commit 86872cb

File tree

5 files changed

+259
-200
lines changed

5 files changed

+259
-200
lines changed

include/net/ip6_fib.h

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,35 @@
1616
#ifdef __KERNEL__
1717

1818
#include <linux/ipv6_route.h>
19-
20-
#include <net/dst.h>
21-
#include <net/flow.h>
2219
#include <linux/rtnetlink.h>
2320
#include <linux/spinlock.h>
21+
#include <net/dst.h>
22+
#include <net/flow.h>
23+
#include <net/netlink.h>
2424

2525
struct rt6_info;
2626

27+
struct fib6_config
28+
{
29+
u32 fc_table;
30+
u32 fc_metric;
31+
int fc_dst_len;
32+
int fc_src_len;
33+
int fc_ifindex;
34+
u32 fc_flags;
35+
u32 fc_protocol;
36+
37+
struct in6_addr fc_dst;
38+
struct in6_addr fc_src;
39+
struct in6_addr fc_gateway;
40+
41+
unsigned long fc_expires;
42+
struct nlattr *fc_mx;
43+
int fc_mx_len;
44+
45+
struct nl_info fc_nlinfo;
46+
};
47+
2748
struct fib6_node
2849
{
2950
struct fib6_node *parent;
@@ -175,18 +196,13 @@ extern void fib6_clean_all(int (*func)(struct rt6_info *, void *arg),
175196

176197
extern int fib6_add(struct fib6_node *root,
177198
struct rt6_info *rt,
178-
struct nlmsghdr *nlh,
179-
void *rtattr,
180-
struct netlink_skb_parms *req);
199+
struct nl_info *info);
181200

182201
extern int fib6_del(struct rt6_info *rt,
183-
struct nlmsghdr *nlh,
184-
void *rtattr,
185-
struct netlink_skb_parms *req);
202+
struct nl_info *info);
186203

187204
extern void inet6_rt_notify(int event, struct rt6_info *rt,
188-
struct nlmsghdr *nlh,
189-
struct netlink_skb_parms *req);
205+
struct nl_info *info);
190206

191207
extern void fib6_run_gc(unsigned long dummy);
192208

include/net/ip6_route.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,7 @@ extern void ip6_route_cleanup(void);
6060

6161
extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
6262

63-
extern int ip6_route_add(struct in6_rtmsg *rtmsg,
64-
struct nlmsghdr *,
65-
void *rtattr,
66-
struct netlink_skb_parms *req,
67-
u32 table_id);
63+
extern int ip6_route_add(struct fib6_config *cfg);
6864
extern int ip6_ins_rt(struct rt6_info *);
6965
extern int ip6_del_rt(struct rt6_info *);
7066

net/ipv6/addrconf.c

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,59 +1509,56 @@ static void
15091509
addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
15101510
unsigned long expires, u32 flags)
15111511
{
1512-
struct in6_rtmsg rtmsg;
1512+
struct fib6_config cfg = {
1513+
.fc_table = RT6_TABLE_PREFIX,
1514+
.fc_metric = IP6_RT_PRIO_ADDRCONF,
1515+
.fc_ifindex = dev->ifindex,
1516+
.fc_expires = expires,
1517+
.fc_dst_len = plen,
1518+
.fc_flags = RTF_UP | flags,
1519+
};
15131520

1514-
memset(&rtmsg, 0, sizeof(rtmsg));
1515-
ipv6_addr_copy(&rtmsg.rtmsg_dst, pfx);
1516-
rtmsg.rtmsg_dst_len = plen;
1517-
rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
1518-
rtmsg.rtmsg_ifindex = dev->ifindex;
1519-
rtmsg.rtmsg_info = expires;
1520-
rtmsg.rtmsg_flags = RTF_UP|flags;
1521-
rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1521+
ipv6_addr_copy(&cfg.fc_dst, pfx);
15221522

15231523
/* Prevent useless cloning on PtP SIT.
15241524
This thing is done here expecting that the whole
15251525
class of non-broadcast devices need not cloning.
15261526
*/
1527-
if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT))
1528-
rtmsg.rtmsg_flags |= RTF_NONEXTHOP;
1527+
if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
1528+
cfg.fc_flags |= RTF_NONEXTHOP;
15291529

1530-
ip6_route_add(&rtmsg, NULL, NULL, NULL, RT6_TABLE_PREFIX);
1530+
ip6_route_add(&cfg);
15311531
}
15321532

15331533
/* Create "default" multicast route to the interface */
15341534

15351535
static void addrconf_add_mroute(struct net_device *dev)
15361536
{
1537-
struct in6_rtmsg rtmsg;
1538-
1539-
memset(&rtmsg, 0, sizeof(rtmsg));
1540-
ipv6_addr_set(&rtmsg.rtmsg_dst,
1541-
htonl(0xFF000000), 0, 0, 0);
1542-
rtmsg.rtmsg_dst_len = 8;
1543-
rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
1544-
rtmsg.rtmsg_ifindex = dev->ifindex;
1545-
rtmsg.rtmsg_flags = RTF_UP;
1546-
rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1547-
ip6_route_add(&rtmsg, NULL, NULL, NULL, RT6_TABLE_LOCAL);
1537+
struct fib6_config cfg = {
1538+
.fc_table = RT6_TABLE_LOCAL,
1539+
.fc_metric = IP6_RT_PRIO_ADDRCONF,
1540+
.fc_ifindex = dev->ifindex,
1541+
.fc_dst_len = 8,
1542+
.fc_flags = RTF_UP,
1543+
};
1544+
1545+
ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
1546+
1547+
ip6_route_add(&cfg);
15481548
}
15491549

15501550
static void sit_route_add(struct net_device *dev)
15511551
{
1552-
struct in6_rtmsg rtmsg;
1553-
1554-
memset(&rtmsg, 0, sizeof(rtmsg));
1555-
1556-
rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1557-
rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
1552+
struct fib6_config cfg = {
1553+
.fc_table = RT6_TABLE_MAIN,
1554+
.fc_metric = IP6_RT_PRIO_ADDRCONF,
1555+
.fc_ifindex = dev->ifindex,
1556+
.fc_dst_len = 96,
1557+
.fc_flags = RTF_UP | RTF_NONEXTHOP,
1558+
};
15581559

15591560
/* prefix length - 96 bits "::d.d.d.d" */
1560-
rtmsg.rtmsg_dst_len = 96;
1561-
rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP;
1562-
rtmsg.rtmsg_ifindex = dev->ifindex;
1563-
1564-
ip6_route_add(&rtmsg, NULL, NULL, NULL, RT6_TABLE_MAIN);
1561+
ip6_route_add(&cfg);
15651562
}
15661563

15671564
static void addrconf_add_lroute(struct net_device *dev)

net/ipv6/ip6_fib.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
610610
*/
611611

612612
static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
613-
struct nlmsghdr *nlh, struct netlink_skb_parms *req)
613+
struct nl_info *info)
614614
{
615615
struct rt6_info *iter = NULL;
616616
struct rt6_info **ins;
@@ -665,7 +665,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
665665
*ins = rt;
666666
rt->rt6i_node = fn;
667667
atomic_inc(&rt->rt6i_ref);
668-
inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req);
668+
inet6_rt_notify(RTM_NEWROUTE, rt, info);
669669
rt6_stats.fib_rt_entries++;
670670

671671
if ((fn->fn_flags & RTN_RTINFO) == 0) {
@@ -695,8 +695,7 @@ void fib6_force_start_gc(void)
695695
* with source addr info in sub-trees
696696
*/
697697

698-
int fib6_add(struct fib6_node *root, struct rt6_info *rt,
699-
struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
698+
int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info)
700699
{
701700
struct fib6_node *fn;
702701
int err = -ENOMEM;
@@ -769,7 +768,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
769768
}
770769
#endif
771770

772-
err = fib6_add_rt2node(fn, rt, nlh, req);
771+
err = fib6_add_rt2node(fn, rt, info);
773772

774773
if (err == 0) {
775774
fib6_start_gc(rt);
@@ -1076,7 +1075,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
10761075
}
10771076

10781077
static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
1079-
struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
1078+
struct nl_info *info)
10801079
{
10811080
struct fib6_walker_t *w;
10821081
struct rt6_info *rt = *rtp;
@@ -1132,11 +1131,11 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
11321131
if (atomic_read(&rt->rt6i_ref) != 1) BUG();
11331132
}
11341133

1135-
inet6_rt_notify(RTM_DELROUTE, rt, nlh, req);
1134+
inet6_rt_notify(RTM_DELROUTE, rt, info);
11361135
rt6_release(rt);
11371136
}
11381137

1139-
int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
1138+
int fib6_del(struct rt6_info *rt, struct nl_info *info)
11401139
{
11411140
struct fib6_node *fn = rt->rt6i_node;
11421141
struct rt6_info **rtp;
@@ -1161,7 +1160,7 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct ne
11611160

11621161
for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
11631162
if (*rtp == rt) {
1164-
fib6_del_route(fn, rtp, nlh, _rtattr, req);
1163+
fib6_del_route(fn, rtp, info);
11651164
return 0;
11661165
}
11671166
}
@@ -1290,7 +1289,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
12901289
res = c->func(rt, c->arg);
12911290
if (res < 0) {
12921291
w->leaf = rt;
1293-
res = fib6_del(rt, NULL, NULL, NULL);
1292+
res = fib6_del(rt, NULL);
12941293
if (res) {
12951294
#if RT6_DEBUG >= 2
12961295
printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);

0 commit comments

Comments
 (0)