This checkin addresses a couple of issues:

1. The "route" command allows route insertion through the interface-direct
   option "-iface". During if_attach(), an sockaddr_dl{} entry is created
   for the interface and is part of the interface address list. This
   sockaddr_dl{} entry describes the interface in detail. The "route"
   command selects this entry as the "gateway" object when the "-iface"
   option is present. The "arp" and "ndp" commands also interact with the
   kernel through the routing socket when adding and removing static L2
   entries. The static L2 information is also provided through the
   "gateway" object with an AF_LINK family type, similar to what is
   provided by the "route" command. In order to differentiate between
   these two types of operations, a RTF_LLDATA flag is introduced. This
   flag is set by the "arp" and "ndp" commands when issuing the add and
   delete commands. This flag is also set in each L2 entry returned by the
   kernel. The "arp" and "ndp" command follows a convention where a RTM_GET
   is issued first followed by a RTM_ADD/DELETE. This RTM_GET request fills
   in the fields for a "rtm" object, which is reinjected into the kernel by
   a subsequent RTM_ADD/DELETE command. The entry returend from RTM_GET
   is a prefix route, so the RTF_LLDATA flag must be specified when issuing
   the RTM_ADD/DELETE messages.

2. Enforce the convention that NET_RT_FLAGS with a 0 w_arg is the
   specification for retrieving L2 information. Also optimized the
   code logic.

Reviewed by:   julian
This commit is contained in:
Qing Li 2008-12-26 19:45:24 +00:00
parent 491c34ec7e
commit 8eca593c5a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=186500
6 changed files with 28 additions and 11 deletions

View File

@ -174,6 +174,7 @@ struct ortentry {
/* 0x100 unused, was RTF_CLONING */
#define RTF_XRESOLVE 0x200 /* external daemon resolves name */
/* 0x400 unused, was RTF_LLINFO */
#define RTF_LLDATA 0x400 /* used by apps to add/del L2 entries */
#define RTF_STATIC 0x800 /* manually added */
#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */
#define RTF_PROTO2 0x4000 /* protocol specific routing flag */

View File

@ -53,6 +53,7 @@
#include <sys/vimage.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_llatbl.h>
#include <net/netisr.h>
#include <net/raw_cb.h>
@ -514,8 +515,10 @@ route_output(struct mbuf *m, struct socket *so)
if (info.rti_info[RTAX_GATEWAY] == NULL)
senderr(EINVAL);
saved_nrt = NULL;
/* support for new ARP code */
if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) {
if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK &&
(rtm->rtm_flags & RTF_LLDATA) != 0) {
error = lla_rt_output(rtm, &info);
break;
}
@ -535,7 +538,8 @@ route_output(struct mbuf *m, struct socket *so)
saved_nrt = NULL;
/* support for new ARP code */
if (info.rti_info[RTAX_GATEWAY] &&
(info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK)) {
(info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) &&
(rtm->rtm_flags & RTF_LLDATA) != 0) {
error = lla_rt_output(rtm, &info);
break;
}
@ -1427,6 +1431,21 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
lim = AF_MAX;
} else /* dump only one table */
i = lim = af;
/*
* take care of llinfo entries, the caller must
* specify an AF
*/
if (w.w_op == NET_RT_FLAGS && w.w_arg == 0) {
if (af != 0)
error = lltable_sysctl_dumparp(af, w.w_req);
else
error = EINVAL;
break;
}
/*
* take care of routing entries
*/
for (error = 0; error == 0 && i <= lim; i++)
if ((rnh = V_rt_tables[curthread->td_proc->p_fibnum][i]) != NULL) {
RADIX_NODE_HEAD_LOCK(rnh);
@ -1435,11 +1454,6 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
RADIX_NODE_HEAD_UNLOCK(rnh);
} else if (af != 0)
error = EAFNOSUPPORT;
/*
* take care of llinfo entries
*/
if (w.w_op == NET_RT_FLAGS)
error = lltable_sysctl_dumparp(af, w.w_req);
break;
case NET_RT_IFLIST:

View File

@ -1222,7 +1222,7 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
arpc.rtm.rtm_rmx.rmx_expire =
lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
arpc.rtm.rtm_flags |= RTF_HOST;
arpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA);
if (lle->la_flags & LLE_STATIC)
arpc.rtm.rtm_flags |= RTF_STATIC;
arpc.rtm.rtm_index = ifp->if_index;

View File

@ -2282,7 +2282,7 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
ndpc.rtm.rtm_rmx.rmx_expire =
lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
ndpc.rtm.rtm_flags |= RTF_HOST;
ndpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA);
if (lle->la_flags & LLE_STATIC)
ndpc.rtm.rtm_flags |= RTF_STATIC;
ndpc.rtm.rtm_index = ifp->if_index;

View File

@ -477,6 +477,7 @@ delete(char *host, int do_proxy)
}
dst->sin_other = SIN_PROXY;
}
rtm->rtm_flags |= RTF_LLDATA;
if (rtmsg(RTM_DELETE, dst, NULL) != NULL) {
printf("%s (%s) deleted\n", host, inet_ntoa(addr->sin_addr));
return (0);
@ -706,7 +707,7 @@ rtmsg(int cmd, struct sockaddr_inarp *dst, struct sockaddr_dl *sdl)
rtm->rtm_addrs |= RTA_GATEWAY;
rtm->rtm_rmx.rmx_expire = expire_time;
rtm->rtm_inits = RTV_EXPIRE;
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);
dst->sin_other = 0;
if (doing_proxy) {
if (proxy_only)

View File

@ -554,6 +554,7 @@ delete:
* but we want the actual address
*/
NEXTADDR(RTA_DST, sin_m);
rtm->rtm_flags |= RTF_LLDATA;
if (rtmsg(RTM_DELETE) == 0) {
struct sockaddr_in6 s6 = *sin; /* XXX: for safety */
@ -895,7 +896,7 @@ rtmsg(cmd)
rtm->rtm_rmx.rmx_expire = expire_time;
rtm->rtm_inits = RTV_EXPIRE;
}
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);
#if 0 /* we don't support ipv6addr/128 type proxying */
if (rtm->rtm_flags & RTF_ANNOUNCE) {
rtm->rtm_flags &= ~RTF_HOST;