Index: sys/net/route.h =================================================================== RCS file: /cvs/src/sys/net/route.h,v diff -u -p -r1.210 route.h --- sys/net/route.h 31 Mar 2024 15:53:12 -0000 1.210 +++ sys/net/route.h 30 Aug 2024 02:33:57 -0000 @@ -163,6 +166,7 @@ struct rtentry { #define RTF_CLONED 0x10000 /* this is a cloned route */ #define RTF_CACHED 0x20000 /* cached by a RTF_GATEWAY entry */ #define RTF_MPATH 0x40000 /* multipath route or operation */ +#define RTF_NSRCADDR 0x80000 /* no route sourceaddr selection */ #define RTF_MPLS 0x100000 /* MPLS additional infos */ #define RTF_LOCAL 0x200000 /* route to a local address */ #define RTF_BROADCAST 0x400000 /* route associated to a bcast addr. */ @@ -172,7 +176,7 @@ struct rtentry { /* mask of RTF flags that are allowed to be modified by RTM_CHANGE */ #define RTF_FMASK \ (RTF_LLINFO | RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_BLACKHOLE | \ - RTF_REJECT | RTF_STATIC | RTF_MPLS | RTF_BFD) + RTF_REJECT | RTF_STATIC | RTF_NSRCADDR | RTF_MPLS | RTF_BFD) /* Routing priorities used by the different routing protocols */ #define RTP_NONE 0 /* unset priority use sane default */ Index: sys/netinet/in_pcb.c =================================================================== RCS file: /cvs/src/sys/netinet/in_pcb.c,v diff -u -p -r1.303 in_pcb.c --- sys/netinet/in_pcb.c 12 Jul 2024 19:50:35 -0000 1.303 +++ sys/netinet/in_pcb.c 30 Aug 2024 02:33:57 -0000 @@ -980,8 +980,8 @@ in_pcbselsrc(struct in_addr *insrc, stru * - preferred source address is set * - output interface is UP */ - if (rt != NULL && !(rt->rt_flags & RTF_LLINFO) && - !(rt->rt_flags & RTF_HOST)) { + if (rt != NULL && + !ISSET(rt->rt_flags, RTF_LLINFO|RTF_HOST|RTF_NSRCADDR)) { ip4_source = rtable_getsource(rtableid, AF_INET); if (ip4_source != NULL) { struct ifaddr *ifa; Index: sys/netinet6/in6_src.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_src.c,v diff -u -p -r1.99 in6_src.c --- sys/netinet6/in6_src.c 21 Apr 2024 17:32:11 -0000 1.99 +++ sys/netinet6/in6_src.c 30 Aug 2024 02:33:57 -0000 @@ -205,8 +205,8 @@ in6_pcbselsrc(const struct in6_addr **in * - preferred source address is set * - output interface is UP */ - if (rt != NULL && !(rt->rt_flags & RTF_LLINFO) && - !(rt->rt_flags & RTF_HOST)) { + if (rt != NULL && + !ISSET(rt->rt_flags, RTF_LLINFO|RTF_HOST|RTF_NSRCADDR)) { ip6_source = rtable_getsource(rtableid, AF_INET6); if (ip6_source != NULL) { struct ifaddr *ifa; Index: sbin/route/keywords.h =================================================================== RCS file: /cvs/src/sbin/route/keywords.h,v diff -u -p -r1.36 keywords.h --- sbin/route/keywords.h 4 Aug 2021 18:17:23 -0000 1.36 +++ sbin/route/keywords.h 30 Aug 2024 02:33:57 -0000 @@ -51,6 +51,7 @@ enum { K_NOBFD, K_NOJUMBO, K_NOSTATIC, + K_NOSOURCEADDR, K_OSPF, K_OUT, K_POP, @@ -115,6 +116,7 @@ struct keytab keywords[] = { { "netmask", K_NETMASK }, { "nobfd", K_NOBFD }, { "nojumbo", K_NOJUMBO }, + { "nosourceaddr", K_NOSOURCEADDR }, { "nostatic", K_NOSTATIC }, { "ospf", K_OSPF }, { "out", K_OUT }, Index: sbin/route/keywords.sh =================================================================== RCS file: /cvs/src/sbin/route/keywords.sh,v diff -u -p -r1.34 keywords.sh --- sbin/route/keywords.sh 4 Aug 2021 18:17:23 -0000 1.34 +++ sbin/route/keywords.sh 30 Aug 2024 02:33:57 -0000 @@ -51,6 +51,7 @@ net netmask nobfd nojumbo +nosourceaddr nostatic ospf out Index: sbin/route/route.8 =================================================================== RCS file: /cvs/src/sbin/route/route.8,v diff -u -p -r1.119 route.8 --- sbin/route/route.8 2 Aug 2023 23:34:13 -0000 1.119 +++ sbin/route/route.8 30 Aug 2024 02:33:57 -0000 @@ -123,7 +123,7 @@ Various flags can be set on routes (viewable using .Cm show ) : .Pp -.Bl -tag -width -blackhole -compact +.Bl -tag -width -nosourceaddr -compact .It Fl blackhole silently discard packets .It Fl cloning @@ -136,6 +136,8 @@ validly translates address to link addre multiple gateways for a destination exist .It Fl nostatic pretend route added by kernel or daemon +.It Fl nosourceaddr +do not use route sourceaddr for address selection .It Fl proto1 sets protocol specific routing flag #1 .It Fl proto2 @@ -144,6 +146,8 @@ sets protocol specific routing flag #2 emits an ICMP unreachable when matched .It Fl static manually added route (default) +.It Fl sourceaddr +use route sourceaddr for address selection (default) .El .Pp The @@ -421,6 +425,7 @@ The mapping between letters and flags is .It Dv P Ta Dv RTF_MPATH Ta "Multipath route." .It Dv R Ta Dv RTF_REJECT Ta "Host or net unreachable." .It Dv S Ta Dv RTF_STATIC Ta "Manually added." +.It Dv s Ta Dv RTF_NSRCADDR Ta "Do not use route sourceaddr." .It Dv T Ta Dv RTF_MPLS Ta "MPLS route." .It Dv U Ta Dv RTF_UP Ta "Route usable." .El Index: sbin/route/route.c =================================================================== RCS file: /cvs/src/sbin/route/route.c,v diff -u -p -r1.267 route.c --- sbin/route/route.c 9 May 2024 08:35:40 -0000 1.267 +++ sbin/route/route.c 30 Aug 2024 02:33:57 -0000 @@ -658,6 +658,9 @@ newroute(int argc, char **argv) case K_NOSTATIC: flags &= ~RTF_STATIC; break; + case K_SOURCEADDR: + flags &= ~RTF_NSRCADDR; + break; case K_LLINFO: flags |= RTF_LLINFO; break; @@ -688,6 +691,9 @@ newroute(int argc, char **argv) case K_STATIC: flags |= RTF_STATIC; break; + case K_NOSOURCEADDR: + flags |= RTF_NSRCADDR; + break; case K_IFA: if (!--argc) usage(1+*argv); @@ -1398,11 +1404,11 @@ char *msgtypes[] = { char metricnames[] = "\011priority\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu"; -char routeflags[] = -"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010XMASK_PRESENT" -"\011CLONING\012MULTICAST\013LLINFO\014STATIC\015BLACKHOLE\016PROTO3\017PROTO2" -"\020PROTO1\021CLONED\022CACHED\023MPATH\025MPLS\026LOCAL\027BROADCAST" -"\030CONNECTED\031BFD"; +char routeflags[] = "\1UP" "\2GATEWAY" "\3HOST" "\4REJECT" "\5DYNAMIC" + "\6MODIFIED" "\7DONE" "\010XMASK_PRESENT" "\011CLONING" "\012MULTICAST" + "\013LLINFO" "\014STATIC" "\015BLACKHOLE" "\016PROTO3" "\017PROTO2" + "\020PROTO1" "\021CLONED" "\022CACHED" "\023MPATH" "\024NSRCADDR" + "\025MPLS" "\026LOCAL" "\027BROADCAST" "\030CONNECTED" "\031BFD"; char ifnetflags[] = "\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6STATICARP\7RUNNING\010NOARP\011PPROMISC" "\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST" Index: sbin/route/show.c =================================================================== RCS file: /cvs/src/sbin/route/show.c,v diff -u -p -r1.122 show.c --- sbin/route/show.c 15 Mar 2023 08:42:14 -0000 1.122 +++ sbin/route/show.c 30 Aug 2024 02:33:57 -0000 @@ -88,6 +88,7 @@ static const struct bits bits[] = { { RTF_CLONED, 'c' }, { RTF_CACHED, 'h' }, { RTF_MPATH, 'P' }, + { RTF_NSRCADDR, 's' }, { RTF_MPLS, 'T' }, { RTF_LOCAL, 'l' }, { RTF_BFD, 'F' }, Index: usr.bin/netstat/show.c =================================================================== RCS file: /cvs/src/usr.bin/netstat/show.c,v diff -u -p -r1.60 show.c --- usr.bin/netstat/show.c 9 Nov 2022 18:00:02 -0000 1.60 +++ usr.bin/netstat/show.c 30 Aug 2024 02:33:57 -0000 @@ -87,6 +87,7 @@ static const struct bits bits[] = { { RTF_CLONED, 'c' }, { RTF_CACHED, 'h' }, { RTF_MPATH, 'P' }, + { RTF_NSRCADDR, 's' }, { RTF_MPLS, 'T' }, { RTF_LOCAL, 'l' }, { RTF_BFD, 'F' }, Index: usr.sbin/relayd/agentx_control.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/agentx_control.c,v diff -u -p -r1.7 agentx_control.c --- usr.sbin/relayd/agentx_control.c 17 Jan 2024 10:01:24 -0000 1.7 +++ usr.sbin/relayd/agentx_control.c 30 Aug 2024 02:33:57 -0000 @@ -711,7 +711,7 @@ agentxctl_router(struct agentx_varbind * } else if (agentx_varbind_get_object(sav) == relaydRouterName) agentx_varbind_string(sav, router->rt_conf.name); else if (agentx_varbind_get_object(sav) == relaydRouterLabel) - agentx_varbind_string(sav, router->rt_conf.label); + agentx_varbind_string(sav, NULL); else if (agentx_varbind_get_object(sav) == relaydRouterRtable) agentx_varbind_integer(sav, router->rt_conf.rtable); } Index: usr.sbin/relayd/parse.y =================================================================== RCS file: /cvs/src/usr.sbin/relayd/parse.y,v diff -u -p -r1.257 parse.y --- usr.sbin/relayd/parse.y 10 Aug 2024 05:47:29 -0000 1.257 +++ usr.sbin/relayd/parse.y 30 Aug 2024 02:33:57 -0000 @@ -179,7 +179,8 @@ typedef struct { %token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS -%token WEBSOCKETS PFLOG +%token WEBSOCKETS PFLOG SOURCEADDR +%token NONE LOCAL CONNECTED STATIC OSPF ISIS RIP BGP DEFAULT %token STRING %token NUMBER %type context hostname interface table value path @@ -188,6 +189,7 @@ typedef struct { %type opttls opttlsclient %type redirect_proto relay_proto match pflog %type action ruleaf key_option +%type rtprio %type port %type host %type address rulesrc ruledst addrprefix @@ -539,7 +541,7 @@ rdropts_l : rdropts_l rdroptsl nl | rdroptsl optnl ; -rdroptsl : forwardmode TO tablespec interface { +rdroptsl : forwardmode TO tablespec { if (hashkey != NULL) { memcpy(&rdr->conf.key, hashkey, sizeof(rdr->conf.key)); @@ -548,36 +550,6 @@ rdroptsl : forwardmode TO tablespec inte hashkey = NULL; } - switch ($1) { - case FWD_NORMAL: - if ($4 == NULL) - break; - yyerror("superfluous interface"); - free($4); - YYERROR; - case FWD_ROUTE: - if ($4 != NULL) - break; - yyerror("missing interface to route to"); - free($4); - YYERROR; - case FWD_TRANS: - yyerror("no transparent forward here"); - if ($4 != NULL) - free($4); - YYERROR; - } - if ($4 != NULL) { - if (strlcpy($3->conf.ifname, $4, - sizeof($3->conf.ifname)) >= - sizeof($3->conf.ifname)) { - yyerror("interface name truncated"); - free($4); - YYERROR; - } - free($4); - } - if ($3->conf.check == CHECK_NOCHECK) { yyerror("table %s has no check", $3->conf.name); purge_table(conf, conf->sc_tables, $3); @@ -2097,8 +2069,8 @@ router : ROUTER STRING { router = rt; tableport = -1; - } '{' optnl routeopts_l '}' { - if (!router->rt_conf.nroutes) { + } '{' optnl routeropts_l '}' { + if (TAILQ_EMPTY(&router->rt_netroutes)) { yyerror("router %s without routes", router->rt_conf.name); free(router); @@ -2114,11 +2086,11 @@ router : ROUTER STRING { } ; -routeopts_l : routeopts_l routeoptsl nl - | routeoptsl optnl +routeropts_l : routeropts_l routeroptsl nl + | routeroptsl optnl ; -routeoptsl : ROUTE addrprefix { +routeroptsl : ROUTE addrprefix { struct netroute *nr; if (router->rt_conf.af == AF_UNSPEC) @@ -2139,15 +2111,15 @@ routeoptsl : ROUTE addrprefix { YYERROR; } nr->nr_conf.prefixlen = $2.prefixlen; + nr->nr_conf.priority = RTP_DEFAULT; nr->nr_conf.routerid = router->rt_conf.id; nr->nr_router = router; bcopy(&$2.ss, &nr->nr_conf.ss, sizeof($2.ss)); - router->rt_conf.nroutes++; - conf->sc_routecount++; TAILQ_INSERT_TAIL(&router->rt_netroutes, nr, nr_entry); + conf->sc_routecount++; TAILQ_INSERT_TAIL(conf->sc_routes, nr, nr_route); - } + } routeopts_l | FORWARD TO tablespec { free(hashkey); hashkey = NULL; @@ -2175,18 +2147,80 @@ routeoptsl : ROUTE addrprefix { } router->rt_conf.rtable = $2; } - | RTLABEL STRING { - if (strlcpy(router->rt_conf.label, $2, - sizeof(router->rt_conf.label)) >= - sizeof(router->rt_conf.label)) { - yyerror("route label truncated"); + | DISABLE { rlay->rl_conf.flags |= F_DISABLE; } + | include + ; + +routeopts_l : routeopts_l routeoptsl + | routeoptsl + | /* empty */ + ; + +routeoptsl : INTERFACE STRING { + struct netroute *nr = + TAILQ_LAST(&router->rt_netroutes, netroutelist); + struct netroute_config *c = &nr->nr_conf; + size_t len; + + if (strlen(c->ifname)) { + yyerror("interface name already defined"); free($2); YYERROR; } + + len = strlcpy(c->ifname, $2, sizeof(c->ifname)); free($2); + + if (len >= sizeof(c->ifname)) { + yyerror("interface name truncated"); + YYERROR; + } + } + | PRIORITY rtprio { + struct netroute *nr = + TAILQ_LAST(&router->rt_netroutes, netroutelist); + struct netroute_config *c = &nr->nr_conf; + + c->priority = $2; + } + | RTLABEL STRING { + struct netroute *nr = + TAILQ_LAST(&router->rt_netroutes, netroutelist); + struct netroute_config *c = &nr->nr_conf; + size_t len; + + len = strlcpy(c->label, $2, sizeof(c->label)); + free($2); + + if (len >= sizeof(c->label)) { + yyerror("route label truncated"); + YYERROR; + } + } + | NO ROUTE SOURCEADDR { + struct netroute *nr = + TAILQ_LAST(&router->rt_netroutes, netroutelist); + struct netroute_config *c = &nr->nr_conf; + c->rt_flags |= RTF_NSRCADDR; + } + ; + +rtprio : NONE { $$ = RTP_NONE; } + | LOCAL { $$ = RTP_LOCAL; } + | CONNECTED { $$ = RTP_CONNECTED; } + | STATIC { $$ = RTP_STATIC; } + | OSPF { $$ = RTP_OSPF; } + | ISIS { $$ = RTP_ISIS; } + | RIP { $$ = RTP_RIP; } + | BGP { $$ = RTP_BGP; } + | DEFAULT { $$ = RTP_DEFAULT; } + | NUMBER { + if ($1 < 0 || $1 > RTP_MAX) { + yyerror("invalid priority value: %lld\n", $1); + YYERROR; + } + $$ = $1; } - | DISABLE { rlay->rl_conf.flags |= F_DISABLE; } - | include ; dstaf : /* empty */ { @@ -2264,17 +2298,6 @@ hostflags : RETRY NUMBER { } hst->conf.parentid = $2; } - | PRIORITY NUMBER { - if (hst->conf.priority) { - yyerror("priority already set"); - YYERROR; - } - if ($2 < 0 || $2 > RTP_MAX) { - yyerror("invalid priority value: %lld\n", $2); - YYERROR; - } - hst->conf.priority = $2; - } | IP TTL NUMBER { if (hst->conf.ttl) { yyerror("ttl value already set"); @@ -2401,6 +2424,7 @@ lookup(char *s) { "append", APPEND }, { "backlog", BACKLOG }, { "backup", BACKUP }, + { "bgp", BGP }, { "binary", BINARY }, { "block", BLOCK }, { "buffer", BUFFER }, @@ -2412,9 +2436,11 @@ lookup(char *s) { "checks", CHECKS }, { "ciphers", CIPHERS }, { "code", CODE }, + { "connected", CONNECTED }, { "connection", CONNECTION }, { "context", CONTEXT }, { "cookie", COOKIE }, + { "default", DEFAULT }, { "demote", DEMOTE }, { "destination", DESTINATION }, { "digest", DIGEST }, @@ -2440,12 +2466,14 @@ lookup(char *s) { "interface", INTERFACE }, { "interval", INTERVAL }, { "ip", IP }, + { "isis", ISIS }, { "key", KEY }, { "keypair", KEYPAIR }, { "label", LABEL }, { "least-states", LEASTSTATES }, { "listen", LISTEN }, { "loadbalance", LOADBALANCE }, + { "local", LOCAL }, { "log", LOG }, { "lookup", LOOKUP }, { "match", MATCH }, @@ -2454,8 +2482,10 @@ lookup(char *s) { "nat", NAT }, { "no", NO }, { "nodelay", NODELAY }, + { "none", NONE }, { "nothing", NOTHING }, { "on", ON }, + { "ospf", OSPF }, { "params", PARAMS }, { "parent", PARENT }, { "pass", PASS }, @@ -2478,6 +2508,7 @@ lookup(char *s) { "response", RESPONSE }, { "retry", RETRY }, { "return", RETURN }, + { "rip", RIP }, { "roundrobin", ROUNDROBIN }, { "route", ROUTE }, { "router", ROUTER }, @@ -2490,8 +2521,10 @@ lookup(char *s) { "set", SET }, { "socket", SOCKET }, { "source-hash", SRCHASH }, + { "sourceaddr", SOURCEADDR }, { "splice", SPLICE }, { "state", STATE }, + { "static", STATIC }, { "sticky-address", STICKYADDR }, { "strip", STRIP }, { "style", STYLE }, Index: usr.sbin/relayd/pfe_route.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/pfe_route.c,v diff -u -p -r1.14 pfe_route.c --- usr.sbin/relayd/pfe_route.c 29 Jun 2023 16:24:53 -0000 1.14 +++ usr.sbin/relayd/pfe_route.c 30 Aug 2024 02:33:57 -0000 @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -69,12 +70,14 @@ sync_routes(struct relayd *env, struct r continue; log_debug("%s: " - "router %s route %s/%d gateway %s %s priority %d", + "router %s route %s/%d gateway %s %s priority %d%s", __func__, rt->rt_conf.name, buf, nr->nr_conf.prefixlen, host->conf.name, HOST_ISUP(host->up) ? "up" : "down", - host->conf.priority); + nr->nr_conf.priority, + (nr->nr_conf.rt_flags & RTF_NSRCADDR) ? + " no route sourceaddr" : ""); crt.up = host->up; memcpy(&crt.nr, &nr->nr_conf, sizeof(nr->nr_conf)); @@ -122,10 +125,11 @@ pfe_apply_prefixlen(struct sockaddr_stor int pfe_route(struct relayd *env, struct ctl_netroute *crt) { - struct iovec iov[5]; + struct iovec iov[6]; struct rt_msghdr hdr; struct sockaddr_storage dst, gw, mask, label; struct sockaddr_rtlabel *sr = (struct sockaddr_rtlabel *)&label; + struct sockaddr_dl sdl; int iovcnt = 0; char *gwname; @@ -133,7 +137,8 @@ pfe_route(struct relayd *env, struct ctl hdr.rtm_msglen = sizeof(hdr); hdr.rtm_version = RTM_VERSION; hdr.rtm_type = HOST_ISUP(crt->up) ? RTM_ADD : RTM_DELETE; - hdr.rtm_flags = RTF_STATIC | RTF_GATEWAY | RTF_MPATH; + hdr.rtm_flags = RTF_STATIC | RTF_GATEWAY | RTF_MPATH | + crt->nr.rt_flags; hdr.rtm_seq = env->sc_rtseq++; hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; hdr.rtm_tableid = crt->rt.rtable; @@ -159,12 +164,42 @@ pfe_route(struct relayd *env, struct ctl iov[iovcnt++].iov_len = ROUNDUP(mask.ss_len); hdr.rtm_msglen += ROUNDUP(mask.ss_len); - if (strlen(crt->rt.label)) { - sr->sr_len = sizeof(*sr); - strlcpy(sr->sr_label, crt->rt.label, sizeof(sr->sr_label)); + if (strlen(crt->nr.ifname)) { + unsigned int i = if_nametoindex(crt->nr.ifname); + if (i == 0) { + log_debug("%s: gateway %s: interface %s does not exist", + __func__, gwname, crt->nr.ifname); + return (-1); + } + + memset(&sdl, 0, sizeof(sdl)); + + sdl.sdl_family = AF_LINK; + sdl.sdl_len = sizeof(sdl); + sdl.sdl_index = i; + + iov[iovcnt].iov_base = &sdl; + iov[iovcnt++].iov_len = sizeof(sdl); + + hdr.rtm_msglen += sizeof(sdl); + hdr.rtm_addrs |= RTA_IFP; + } + + if (strlen(crt->nr.label)) { + memset(sr, 0, sizeof(*sr)); + + sr->sr_family = AF_UNSPEC; + sr->sr_len = sizeof(sr); + if (strlcpy(sr->sr_label, crt->nr.label, + sizeof(sr->sr_label)) >= sizeof(sr->sr_label)) { + log_debug("%s: gateway %s: label is too long", + __func__, gwname); + return (-1); + } iov[iovcnt].iov_base = &label; iov[iovcnt++].iov_len = ROUNDUP(label.ss_len); + hdr.rtm_msglen += ROUNDUP(label.ss_len); hdr.rtm_addrs |= RTA_LABEL; } Index: usr.sbin/relayd/relayd.h =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v diff -u -p -r1.274 relayd.h --- usr.sbin/relayd/relayd.h 10 Aug 2024 05:47:29 -0000 1.274 +++ usr.sbin/relayd/relayd.h 30 Aug 2024 02:33:57 -0000 @@ -858,7 +858,11 @@ struct netroute_config { objid_t id; struct sockaddr_storage ss; int prefixlen; + char ifname[IFNAMSIZ]; + char label[RT_LABEL_SIZE]; + int priority; objid_t routerid; + unsigned int rt_flags; }; struct netroute { @@ -875,8 +879,6 @@ struct router_config { objid_t id; u_int32_t flags; char name[HOST_NAME_MAX+1]; - char label[RT_LABEL_SIZE]; - int nroutes; objid_t gwtable; in_port_t gwport; int rtable;