ifstated currently tracks and maintains the index of each monitored interface
and does not maintain interface names. This means we need to re-index on
interface departure and arrival.

The following diff moves away from indexes to names. Indexes are still required,
but easily obtained dynamically as needed. This helps simplify the next diff
that will provide support for interface departure and arrival.

Suggested by deraadt.

No intended functional change. Regress tests pass.

Ok?

Index: ifstated.c
===================================================================
RCS file: /cvs/src/usr.sbin/ifstated/ifstated.c,v
retrieving revision 1.59
diff -u -p -r1.59 ifstated.c
--- ifstated.c  14 Aug 2017 03:15:28 -0000      1.59
+++ ifstated.c  15 Aug 2017 00:34:11 -0000
@@ -61,8 +61,8 @@ void          external_handler(int, short, void 
 void           external_exec(struct ifsd_external *, int);
 void           check_external_status(struct ifsd_state *);
 void           external_evtimer_setup(struct ifsd_state *, int);
-void           scan_ifstate(int, int, int);
-int            scan_ifstate_single(int, int, struct ifsd_state *);
+void           scan_ifstate(const char *, int, int);
+int            scan_ifstate_single(const char *, int, struct ifsd_state *);
 void           fetch_ifstate(int);
 __dead void    usage(void);
 void           adjust_expressions(struct ifsd_expression_list *, int);
@@ -233,6 +233,8 @@ rt_msg_handler(int fd, short event, void
        char msg[2048];
        struct rt_msghdr *rtm = (struct rt_msghdr *)&msg;
        struct if_msghdr ifm;
+       char ifnamebuf[IFNAMSIZ];
+       char *ifname;
        ssize_t len;
 
        if ((len = read(fd, msg, sizeof(msg))) == -1) {
@@ -250,7 +252,10 @@ rt_msg_handler(int fd, short event, void
        switch (rtm->rtm_type) {
        case RTM_IFINFO:
                memcpy(&ifm, rtm, sizeof(ifm));
-               scan_ifstate(ifm.ifm_index, ifm.ifm_data.ifi_link_state, 1);
+               ifname = if_indextoname(ifm.ifm_index, ifnamebuf);
+               /* ifname is NULL on interface departure */
+               if (ifname != NULL)
+                       scan_ifstate(ifname, ifm.ifm_data.ifi_link_state, 1);
                break;
        case RTM_DESYNC:
                fetch_ifstate(1);
@@ -431,7 +436,7 @@ external_evtimer_setup(struct ifsd_state
 #define        LINK_STATE_IS_DOWN(_s)          (!LINK_STATE_IS_UP((_s)))
 
 int
-scan_ifstate_single(int ifindex, int s, struct ifsd_state *state)
+scan_ifstate_single(const char *ifname, int s, struct ifsd_state *state)
 {
        struct ifsd_ifstate *ifstate;
        struct ifsd_expression_list expressions;
@@ -440,7 +445,7 @@ scan_ifstate_single(int ifindex, int s, 
        TAILQ_INIT(&expressions);
 
        TAILQ_FOREACH(ifstate, &state->interface_states, entries) {
-               if (ifstate->ifindex == ifindex) {
+               if (strcmp(ifstate->ifname, ifname) == 0) {
                        if (ifstate->prevstate != s &&
                            (ifstate->prevstate != -1 || !opt_inhibit)) {
                                struct ifsd_expression *expression;
@@ -472,15 +477,15 @@ scan_ifstate_single(int ifindex, int s, 
 }
 
 void
-scan_ifstate(int ifindex, int s, int do_eval)
+scan_ifstate(const char *ifname, int s, int do_eval)
 {
        struct ifsd_state *state;
        int cur_eval = 0;
 
-       if (scan_ifstate_single(ifindex, s, &conf->initstate) && do_eval)
+       if (scan_ifstate_single(ifname, s, &conf->initstate) && do_eval)
                eval_state(&conf->initstate);
        TAILQ_FOREACH(state, &conf->states, entries) {
-               if (scan_ifstate_single(ifindex, s, state) &&
+               if (scan_ifstate_single(ifname, s, state) &&
                    (do_eval && state == conf->curstate))
                        cur_eval = 1;
        }
@@ -619,8 +624,8 @@ fetch_ifstate(int do_eval)
        for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
                if (ifa->ifa_addr->sa_family == AF_LINK) {
                        struct if_data *ifdata = ifa->ifa_data;
-                       scan_ifstate(if_nametoindex(ifa->ifa_name),
-                           ifdata->ifi_link_state, do_eval);
+                       scan_ifstate(ifa->ifa_name, ifdata->ifi_link_state,
+                          do_eval);
                }
        }
 
Index: ifstated.h
===================================================================
RCS file: /cvs/src/usr.sbin/ifstated/ifstated.h,v
retrieving revision 1.18
diff -u -p -r1.18 ifstated.h
--- ifstated.h  14 Aug 2017 03:15:28 -0000      1.18
+++ ifstated.h  15 Aug 2017 00:34:11 -0000
@@ -41,7 +41,7 @@ struct ifsd_ifstate {
 #define IFSD_LINKUP            2
        int                              prevstate;
        u_int32_t                        refcount;
-       u_short                          ifindex;
+       char                             ifname[IFNAMSIZ];
 };
 
 struct ifsd_external {
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/ifstated/parse.y,v
retrieving revision 1.45
diff -u -p -r1.45 parse.y
--- parse.y     23 Jul 2017 13:53:54 -0000      1.45
+++ parse.y     15 Aug 2017 00:34:11 -0000
@@ -85,7 +85,7 @@ struct ifsd_state             *curstate;
 void                    link_states(struct ifsd_action *);
 void                    set_expression_depth(struct ifsd_expression *, int);
 void                    init_state(struct ifsd_state *);
-struct ifsd_ifstate    *new_ifstate(u_short, int);
+struct ifsd_ifstate    *new_ifstate(const char *, int);
 struct ifsd_external   *new_external(char *, u_int32_t);
 
 typedef struct {
@@ -169,15 +169,6 @@ conf_main  : INITSTATE STRING              {
                }
                ;
 
-interface      : STRING                {
-                       if (($$ = if_nametoindex($1)) == 0) {
-                               yyerror("unknown interface %s", $1);
-                               free($1);
-                               YYERROR;
-                       }
-                       free($1);
-               }
-               ;
 
 optnl          : '\n' optnl
                |
@@ -251,13 +242,13 @@ init              : INIT {
                }
                ;
 
-if_test                : interface '.' LINK '.' UP             {
+if_test                : STRING '.' LINK '.' UP                {
                        $$ = new_ifstate($1, IFSD_LINKUP);
                }
-               | interface '.' LINK '.' DOWN           {
+               | STRING '.' LINK '.' DOWN              {
                        $$ = new_ifstate($1, IFSD_LINKDOWN);
                }
-               | interface '.' LINK '.' UNKNOWN        {
+               | STRING '.' LINK '.' UNKNOWN   {
                        $$ = new_ifstate($1, IFSD_LINKUNKNOWN);
                }
                ;
@@ -933,7 +924,7 @@ init_state(struct ifsd_state *state)
 }
 
 struct ifsd_ifstate *
-new_ifstate(u_short ifindex, int s)
+new_ifstate(const char *ifname, int s)
 {
        struct ifsd_ifstate *ifstate = NULL;
        struct ifsd_state *state;
@@ -944,12 +935,15 @@ new_ifstate(u_short ifindex, int s)
                state = &conf->initstate;
 
        TAILQ_FOREACH(ifstate, &state->interface_states, entries)
-               if (ifstate->ifindex == ifindex && ifstate->ifstate == s)
+               if (strcmp(ifstate->ifname, ifname) == 0 &&
+                  ifstate->ifstate == s)
                        break;
        if (ifstate == NULL) {
                if ((ifstate = calloc(1, sizeof(*ifstate))) == NULL)
                        err(1, NULL);
-               ifstate->ifindex = ifindex;
+               if (strlcpy(ifstate->ifname, ifname,
+                  sizeof(ifstate->ifname)) == 0)
+                       errx(1, "ifname strlcpy truncation");
                ifstate->ifstate = s;
                TAILQ_INIT(&ifstate->expressions);
                TAILQ_INSERT_TAIL(&state->interface_states, ifstate, entries);

Reply via email to