]> git.hungrycats.org Git - linux/commitdiff
[IPV6]: Reporting of prefix routes via rtnetlink.
authorKrishna Kumar <krkumar@us.ibm.com>
Tue, 22 Jul 2003 19:58:10 +0000 (12:58 -0700)
committerDavid S. Miller <davem@nuts.ninka.net>
Tue, 22 Jul 2003 19:58:10 +0000 (12:58 -0700)
include/linux/ipv6_route.h
include/linux/rtnetlink.h
net/ipv6/addrconf.c
net/ipv6/route.c

index eacfa6c80f0e1a84eb433ade706f8b4b324e6e1f..46d8b7e8b1aad4d4b96ea34cd2eed393961cb770 100644 (file)
@@ -16,6 +16,7 @@
 #define RTF_DEFAULT    0x00010000      /* default - learned via ND     */
 #define RTF_ALLONLINK  0x00020000      /* fallback, no routers on link */
 #define RTF_ADDRCONF   0x00040000      /* addrconf route - RA          */
+#define RTF_PREFIX_RT  0x00080000      /* A prefix only route - RA     */
 
 #define RTF_NONEXTHOP  0x00200000      /* route with no nexthop        */
 #define RTF_EXPIRES    0x00400000
index 788132027e48d9b73a360d88f26efa7bf2ac2da7..fe336b23e5cba67d2cf9ab186e75495c7cf9d84e 100644 (file)
@@ -168,6 +168,7 @@ enum rt_scope_t
 #define RTM_F_NOTIFY           0x100   /* Notify user of route change  */
 #define RTM_F_CLONED           0x200   /* This route is cloned         */
 #define RTM_F_EQUALIZE         0x400   /* Multipath equalizer: NI      */
+#define RTM_F_PREFIX           0x800   /* Prefix addresses             */
 
 /* Reserved table identifiers */
 
index 649df9f7606879cf6dad305923871b9d459cf107..925effb2390cd28c971b0212a95a782f2c2f8276 100644 (file)
@@ -130,7 +130,7 @@ static spinlock_t addrconf_verify_lock = SPIN_LOCK_UNLOCKED;
 
 static int addrconf_ifdown(struct net_device *dev, int how);
 
-static void addrconf_dad_start(struct inet6_ifaddr *ifp);
+static void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags);
 static void addrconf_dad_timer(unsigned long data);
 static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
 static void addrconf_rs_timer(unsigned long data);
@@ -710,7 +710,7 @@ retry:
        ift->prefered_lft = tmp_prefered_lft;
        ift->tstamp = ifp->tstamp;
        spin_unlock_bh(&ift->lock);
-       addrconf_dad_start(ift);
+       addrconf_dad_start(ift, 0);
        in6_ifa_put(ift);
        in6_dev_put(idev);
 out:
@@ -1247,7 +1247,7 @@ static void addrconf_add_mroute(struct net_device *dev)
        rtmsg.rtmsg_dst_len = 8;
        rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
        rtmsg.rtmsg_ifindex = dev->ifindex;
-       rtmsg.rtmsg_flags = RTF_UP|RTF_ADDRCONF;
+       rtmsg.rtmsg_flags = RTF_UP;
        rtmsg.rtmsg_type = RTMSG_NEWROUTE;
        ip6_route_add(&rtmsg, NULL, NULL);
 }
@@ -1274,7 +1274,7 @@ static void addrconf_add_lroute(struct net_device *dev)
        struct in6_addr addr;
 
        ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
-       addrconf_prefix_route(&addr, 64, dev, 0, RTF_ADDRCONF);
+       addrconf_prefix_route(&addr, 64, dev, 0, 0);
 }
 
 static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
@@ -1367,7 +1367,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
                        }
                } else if (valid_lft) {
                        addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
-                                             dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES);
+                                             dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
                }
                if (rt)
                        dst_release(&rt->u.dst);
@@ -1413,7 +1413,7 @@ ok:
                        }
 
                        update_lft = create = 1;
-                       addrconf_dad_start(ifp);
+                       addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
                }
 
                if (ifp) {
@@ -1586,7 +1586,7 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen)
 
        ifp = ipv6_add_addr(idev, pfx, plen, scope, IFA_F_PERMANENT);
        if (!IS_ERR(ifp)) {
-               addrconf_dad_start(ifp);
+               addrconf_dad_start(ifp, 0);
                in6_ifa_put(ifp);
                return 0;
        }
@@ -1761,7 +1761,7 @@ static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr
 
        ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT);
        if (!IS_ERR(ifp)) {
-               addrconf_dad_start(ifp);
+               addrconf_dad_start(ifp, 0);
                in6_ifa_put(ifp);
        }
 }
@@ -2021,8 +2021,7 @@ static void addrconf_rs_timer(unsigned long data)
                memset(&rtmsg, 0, sizeof(struct in6_rtmsg));
                rtmsg.rtmsg_type = RTMSG_NEWROUTE;
                rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
-               rtmsg.rtmsg_flags = (RTF_ALLONLINK | RTF_ADDRCONF | 
-                                    RTF_DEFAULT | RTF_UP);
+               rtmsg.rtmsg_flags = (RTF_ALLONLINK | RTF_DEFAULT | RTF_UP);
 
                rtmsg.rtmsg_ifindex = ifp->idev->dev->ifindex;
 
@@ -2036,7 +2035,7 @@ out:
 /*
  *     Duplicate Address Detection
  */
-static void addrconf_dad_start(struct inet6_ifaddr *ifp)
+static void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags)
 {
        struct net_device *dev;
        unsigned long rand_num;
@@ -2046,7 +2045,8 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp)
        addrconf_join_solict(dev, &ifp->addr);
 
        if (ifp->prefix_len != 128 && (ifp->flags&IFA_F_PERMANENT))
-               addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 0, RTF_ADDRCONF);
+               addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 0,
+                                       flags);
 
        net_srandom(ifp->addr.s6_addr32[3]);
        rand_num = net_random() % (ifp->idev->cnf.rtr_solicit_delay ? : 1);
index 69d7791712f861c17ae8e416662df314d819e3d4..b3adf22ef02eadd7b8b94ca3b244bc0c7bf1beea 100644 (file)
@@ -1459,13 +1459,20 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
                         struct in6_addr *src,
                         int iif,
                         int type, u32 pid, u32 seq,
-                        struct nlmsghdr *in_nlh)
+                        struct nlmsghdr *in_nlh, int prefix)
 {
        struct rtmsg *rtm;
        struct nlmsghdr  *nlh;
        unsigned char    *b = skb->tail;
        struct rta_cacheinfo ci;
 
+       if (prefix) {   /* user wants prefix routes only */
+               if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
+                       /* success since this is not a prefix route */
+                       return 1;
+               }
+       }
+
        if (!pid && in_nlh) {
                pid = in_nlh->nlmsg_pid;
        }
@@ -1546,10 +1553,17 @@ rtattr_failure:
 static int rt6_dump_route(struct rt6_info *rt, void *p_arg)
 {
        struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg;
+       struct rtmsg *rtm;
+       int prefix;
+
+       rtm = NLMSG_DATA(arg->cb->nlh);
+       if (rtm)
+               prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0;
+       else prefix = 0;
 
        return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
                     NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
-                    NULL);
+                    NULL, prefix);
 }
 
 static int fib6_dump_node(struct fib6_walker_t *w)
@@ -1697,7 +1711,7 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
                            &fl.fl6_dst, &fl.fl6_src,
                            iif,
                            RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
-                           nlh->nlmsg_seq, nlh);
+                           nlh->nlmsg_seq, nlh, 0);
        if (err < 0) {
                err = -EMSGSIZE;
                goto out_free;
@@ -1723,7 +1737,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh)
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS);
                return;
        }
-       if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh) < 0) {
+       if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0) < 0) {
                kfree_skb(skb);
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL);
                return;