aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Olsson <Robert.Olsson@data.slu.se>2005-06-20 16:36:39 -0400
committerDavid S. Miller <davem@davemloft.net>2005-06-20 16:36:39 -0400
commit246955fe4c38bd706ae30e37c64892c94213775d (patch)
tree23583698ce7c58e1643414245690afca33618540
parentf6e276ee67c0ac9efafd24bc6f7a84aa359656df (diff)
[NETLINK]: fib_lookup() via netlink
Below is a more generic patch to do fib_lookup via netlink. For others we should say that we discussed this as a way to verify route selection. It's also possible there are others uses for this. In short the fist half of struct fib_result_nl is filled in by caller and netlink call fills in the other half and returns it. In case anyone is interested there is a corresponding user app to compare the full routing table this was used to test implementation of the LC-trie. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netlink.h1
-rw-r--r--include/net/ip_fib.h14
-rw-r--r--net/ipv4/fib_frontend.c55
3 files changed, 70 insertions, 0 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index e38407a23d04..561d4dc75836 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -14,6 +14,7 @@
14#define NETLINK_SELINUX 7 /* SELinux event notifications */ 14#define NETLINK_SELINUX 7 /* SELinux event notifications */
15#define NETLINK_ARPD 8 15#define NETLINK_ARPD 8
16#define NETLINK_AUDIT 9 /* auditing */ 16#define NETLINK_AUDIT 9 /* auditing */
17#define NETLINK_FIB_LOOKUP 10
17#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */ 18#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */
18#define NETLINK_IP6_FW 13 19#define NETLINK_IP6_FW 13
19#define NETLINK_DNRTMSG 14 /* DECnet routing messages */ 20#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e5a5f6b62f88..a4208a336ac0 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -109,6 +109,20 @@ struct fib_result {
109#endif 109#endif
110}; 110};
111 111
112struct fib_result_nl {
113 u32 fl_addr; /* To be looked up*/
114 u32 fl_fwmark;
115 unsigned char fl_tos;
116 unsigned char fl_scope;
117 unsigned char tb_id_in;
118
119 unsigned char tb_id; /* Results */
120 unsigned char prefixlen;
121 unsigned char nh_sel;
122 unsigned char type;
123 unsigned char scope;
124 int err;
125};
112 126
113#ifdef CONFIG_IP_ROUTE_MULTIPATH 127#ifdef CONFIG_IP_ROUTE_MULTIPATH
114 128
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 563e7d612706..cd8e45ab9580 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -516,6 +516,60 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
516#undef BRD1_OK 516#undef BRD1_OK
517} 517}
518 518
519static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
520{
521
522 struct fib_result res;
523 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
524 .fwmark = frn->fl_fwmark,
525 .tos = frn->fl_tos,
526 .scope = frn->fl_scope } } };
527 if (tb) {
528 local_bh_disable();
529
530 frn->tb_id = tb->tb_id;
531 frn->err = tb->tb_lookup(tb, &fl, &res);
532
533 if (!frn->err) {
534 frn->prefixlen = res.prefixlen;
535 frn->nh_sel = res.nh_sel;
536 frn->type = res.type;
537 frn->scope = res.scope;
538 }
539 local_bh_enable();
540 }
541}
542
543static void nl_fib_input(struct sock *sk, int len)
544{
545 struct sk_buff *skb = NULL;
546 struct nlmsghdr *nlh = NULL;
547 struct fib_result_nl *frn;
548 int err;
549 u32 pid;
550 struct fib_table *tb;
551
552 skb = skb_recv_datagram(sk, 0, 0, &err);
553 nlh = (struct nlmsghdr *)skb->data;
554
555 frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
556 tb = fib_get_table(frn->tb_id_in);
557
558 nl_fib_lookup(frn, tb);
559
560 pid = nlh->nlmsg_pid; /*pid of sending process */
561 NETLINK_CB(skb).groups = 0; /* not in mcast group */
562 NETLINK_CB(skb).pid = 0; /* from kernel */
563 NETLINK_CB(skb).dst_pid = pid;
564 NETLINK_CB(skb).dst_groups = 0; /* unicast */
565 netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
566}
567
568static void nl_fib_lookup_init(void)
569{
570 netlink_kernel_create(NETLINK_FIB_LOOKUP, nl_fib_input);
571}
572
519static void fib_disable_ip(struct net_device *dev, int force) 573static void fib_disable_ip(struct net_device *dev, int force)
520{ 574{
521 if (fib_sync_down(0, dev, force)) 575 if (fib_sync_down(0, dev, force))
@@ -604,6 +658,7 @@ void __init ip_fib_init(void)
604 658
605 register_netdevice_notifier(&fib_netdev_notifier); 659 register_netdevice_notifier(&fib_netdev_notifier);
606 register_inetaddr_notifier(&fib_inetaddr_notifier); 660 register_inetaddr_notifier(&fib_inetaddr_notifier);
661 nl_fib_lookup_init();
607} 662}
608 663
609EXPORT_SYMBOL(inet_addr_type); 664EXPORT_SYMBOL(inet_addr_type);