diff options
Diffstat (limited to 'lib/if.c')
-rw-r--r-- | lib/if.c | 139 |
1 files changed, 118 insertions, 21 deletions
@@ -189,11 +189,13 @@ if_lookup_address (struct in_addr src) listnode node; struct prefix addr; struct prefix best; + struct prefix peer; listnode cnode; struct interface *ifp; struct prefix *p; struct connected *c; struct interface *match; + int prefixlen; /* Zero structures - get rid of rubbish from stack */ memset(&addr, 0, sizeof(addr)); @@ -212,34 +214,24 @@ if_lookup_address (struct in_addr src) for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) { c = getdata (cnode); + p = c->address; - if (if_is_pointopoint (ifp)) + if (p->family == AF_INET) { - p = c->address; + prefixlen = p->prefixlen; - if (p && p->family == AF_INET) + if (if_is_pointopoint (ifp) || + prefixlen >= IPV4_MAX_PREFIXLEN - 1) { -#ifdef OLD_RIB /* PTP links are conventionally identified - by the address of the far end - MAG */ - if (IPV4_ADDR_SAME (&p->u.prefix4, &src)) - return ifp; -#endif - p = c->destination; - if (p && IPV4_ADDR_SAME (&p->u.prefix4, &src)) - return ifp; + peer = *c->destination; + peer.prefixlen = prefixlen; + p = &peer; } - } - else - { - p = c->address; - if (p->family == AF_INET) + if (prefix_match (p, &addr) && prefixlen > best.prefixlen) { - if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen) - { - best = *p; - match = ifp; - } + best = *p; + match = ifp; } } } @@ -270,6 +262,22 @@ if_is_up (struct interface *ifp) return ifp->flags & IFF_UP; } +/* Is interface running? */ +int +if_is_running (struct interface *ifp) +{ + return ifp->flags & IFF_RUNNING; +} + +/* Is the interface operative, eg. either UP & RUNNING + or UP & !ZEBRA_INTERFACE_LINK_DETECTION */ +int +if_is_operative (struct interface *ifp) +{ + return ((ifp->flags & IFF_UP) && + (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))); +} + /* Is this loopback interface ? */ int if_is_loopback (struct interface *ifp) @@ -432,6 +440,36 @@ DEFUN (interface, return CMD_SUCCESS; } +DEFUN_NOSH (no_interface, + no_interface_cmd, + "no interface IFNAME", + NO_STR + "Delete a pseudo interface's configuration\n" + "Interface's name\n") +{ + // deleting interface + struct interface *ifp; + + ifp = if_lookup_by_name (argv[0]); + + if (ifp == NULL) + { + vty_out (vty, "%% Inteface %s does not exist%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) + { + vty_out (vty, "%% Only inactive interfaces can be deleted%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if_delete(ifp); + + return CMD_SUCCESS; +} + /* For debug purpose. */ DEFUN (show_address, show_address_cmd, @@ -553,6 +591,65 @@ connected_delete_by_prefix (struct interface *ifp, struct prefix *p) return NULL; } +/* Find the IPv4 address on our side that will be used when packets + are sent to dst. */ +struct connected * +connected_lookup_address (struct interface *ifp, struct in_addr dst) +{ + struct prefix addr; + struct prefix best; + listnode cnode; + struct prefix *p; + struct connected *c; + struct connected *match; + + /* Zero structures - get rid of rubbish from stack */ + memset(&addr, 0, sizeof(addr)); + memset(&best, 0, sizeof(best)); + + addr.family = AF_INET; + addr.u.prefix4 = dst; + addr.prefixlen = IPV4_MAX_BITLEN; + + match = NULL; + + for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) + { + c = getdata (cnode); + + if (if_is_pointopoint (ifp)) + { + p = c->address; + + if (p && p->family == AF_INET) + { +#ifdef OLD_RIB /* PTP links are conventionally identified + by the address of the far end - MAG */ + if (IPV4_ADDR_SAME (&p->u.prefix4, &dst)) + return c; +#endif + p = c->destination; + if (p && IPV4_ADDR_SAME (&p->u.prefix4, &dst)) + return c; + } + } + else + { + p = c->address; + + if (p->family == AF_INET) + { + if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen) + { + best = *p; + match = c; + } + } + } + } + return match; +} + /* Check the connected information is PtP style or not. */ int ifc_pointopoint (struct connected *ifc) |