diff options
Diffstat (limited to 'zebra/interface.c')
-rw-r--r-- | zebra/interface.c | 304 |
1 files changed, 257 insertions, 47 deletions
diff --git a/zebra/interface.c b/zebra/interface.c index 7a98f649..e19648d7 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -83,6 +83,10 @@ if_zebra_new_hook (struct interface *ifp) rtadv->DefaultPreference = RTADV_PREF_MEDIUM; rtadv->AdvPrefixList = list_new (); + + rtadv->AdvRDNSSFlag = 0; + rtadv->AdvRDNSSLifetime = RTADV_RDNSS_DEFAULT_LIFETIME; + rtadv->AdvRDNSSList = list_new (); } #endif /* RTADV */ @@ -127,7 +131,7 @@ if_subnet_add (struct interface *ifp, struct connected *ifc) /* Get address derived subnet node and associated address list, while marking address secondary attribute appropriately. */ - cp = *ifc->address; + cp = *CONNECTED_PREFIX(ifc); apply_mask (&cp); rn = route_node_get (zebra_if->ipv4_subnets, &cp); @@ -154,12 +158,16 @@ if_subnet_delete (struct interface *ifp, struct connected *ifc) struct route_node *rn; struct zebra_if *zebra_if; struct list *addr_list; + struct prefix cp; assert (ifp && ifp->info && ifc); zebra_if = ifp->info; + cp = *CONNECTED_PREFIX(ifc); + apply_mask (&cp); + /* Get address derived subnet node. */ - rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address); + rn = route_node_lookup (zebra_if->ipv4_subnets, &cp); if (! (rn && rn->info)) return -1; route_unlock_node (rn); @@ -588,8 +596,18 @@ connected_dump_vty (struct vty *vty, struct connected *connected) { vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast ")); prefix_vty_out (vty, connected->destination); + vty_out (vty, "/%d", connected->destination->prefixlen); } +#ifdef HAVE_NETLINK + if (connected->scope != 0) + vty_out (vty, " scope %s", connected_scope_name (connected->scope)); +#endif +#ifdef SIOCSIFADDRPREF + if (connected->preference != 0) + vty_out (vty, " preference %d", connected->preference); +#endif + if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY)) vty_out (vty, " secondary"); @@ -641,6 +659,9 @@ nd_dump_vty (struct vty *vty, struct interface *ifp) vty_out (vty, " ND router advertisements with " "Home Agent flag bit set.%s", VTY_NEWLINE); + if (rtadv->AdvRDNSSFlag) + vty_out (vty, " ND router advertisements with " + "RDNSS information.%s", VTY_NEWLINE); if (rtadv->AdvIntervalOption) vty_out (vty, " ND router advertisements with Adv. Interval option.%s", VTY_NEWLINE); @@ -1196,21 +1217,62 @@ ALIAS (no_bandwidth_if, static int ip_address_install (struct vty *vty, struct interface *ifp, const char *addr_str, const char *peer_str, - const char *label) + const char *label, const char *scope, + const char *preference) { - struct prefix_ipv4 cp; + struct prefix_ipv4 lp, pp; struct connected *ifc; struct prefix_ipv4 *p; int ret; + int scopev = 0, preferencev = 0; - ret = str2prefix_ipv4 (addr_str, &cp); + ret = str2prefix_ipv4 (addr_str, &lp); if (ret <= 0) + { + vty_out (vty, "%% Malformed address %s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (peer_str) { - vty_out (vty, "%% Malformed address %s", VTY_NEWLINE); - return CMD_WARNING; + if (lp.prefixlen != 32) + { + vty_out (vty, "%% Local prefix length for P-t-P address " + "must be /32%s", VTY_NEWLINE); + return CMD_WARNING; + } + + ret = str2prefix_ipv4 (peer_str, &pp); + if (ret <= 0) + { + vty_out (vty, "%% Malformed peer address %s", VTY_NEWLINE); + return CMD_WARNING; + } } - ifc = connected_check (ifp, (struct prefix *) &cp); +#ifdef HAVE_NETLINK + if (scope) + { + scopev = connected_scope_number (scope); + if (scopev < 0) + { + vty_out (vty, "%% Malformed scope %s", VTY_NEWLINE); + return CMD_WARNING; + } + } +#endif + if (preference) + { + preferencev = atoi (preference); + if (preferencev < -32768 || preferencev > 32767) + { + vty_out (vty, "%% Invalid preference %s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + ifc = connected_check_ptp (ifp, (struct prefix *) &lp, + (struct prefix *)(peer_str ? &pp : NULL)); if (! ifc) { ifc = connected_new (); @@ -1218,14 +1280,23 @@ ip_address_install (struct vty *vty, struct interface *ifp, /* Address. */ p = prefix_ipv4_new (); - *p = cp; + *p = lp; ifc->address = (struct prefix *) p; + ifc->scope = scopev; + ifc->preference = preferencev; - /* Broadcast. */ - if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2) + if (peer_str) { + SET_FLAG(ifc->flags, ZEBRA_IFA_PEER); p = prefix_ipv4_new (); - *p = cp; + *p = pp; + ifc->destination = (struct prefix *) p; + } + else if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2) + { + /* Broadcast. */ + p = prefix_ipv4_new (); + *p = lp; p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen); ifc->destination = (struct prefix *) p; } @@ -1280,23 +1351,40 @@ ip_address_install (struct vty *vty, struct interface *ifp, static int ip_address_uninstall (struct vty *vty, struct interface *ifp, - const char *addr_str, const char *peer_str, - const char *label) + const char *addr_str, const char *peer_str) { - struct prefix_ipv4 cp; + struct prefix_ipv4 lp, pp; struct connected *ifc; int ret; /* Convert to prefix structure. */ - ret = str2prefix_ipv4 (addr_str, &cp); + ret = str2prefix_ipv4 (addr_str, &lp); if (ret <= 0) { vty_out (vty, "%% Malformed address %s", VTY_NEWLINE); return CMD_WARNING; } + if (peer_str) + { + if (lp.prefixlen != 32) + { + vty_out (vty, "%% Local prefix length for P-t-P address " + "must be /32%s", VTY_NEWLINE); + return CMD_WARNING; + } + + ret = str2prefix_ipv4 (peer_str, &pp); + if (ret <= 0) + { + vty_out (vty, "%% Malformed peer address %s", VTY_NEWLINE); + return CMD_WARNING; + } + } + /* Check current interface address. */ - ifc = connected_check (ifp, (struct prefix *) &cp); + ifc = connected_check_ptp (ifp, (struct prefix *) &lp, + (struct prefix *)(peer_str ? &pp : NULL)); if (! ifc) { vty_out (vty, "%% Can't find address%s", VTY_NEWLINE); @@ -1326,70 +1414,169 @@ ip_address_uninstall (struct vty *vty, struct interface *ifp, safe_strerror(errno), VTY_NEWLINE); return CMD_WARNING; } + /* success! now update all internal state... */ + + /* Remove connected route. */ + connected_down_ipv4 (ifp, ifc); -#if 0 /* Redistribute this information. */ zebra_interface_address_delete_update (ifp, ifc); - /* Remove connected route. */ - connected_down_ipv4 (ifp, ifc); + /* IP address propery set. */ + UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); + + /* remove from interface, remark secondaries */ + if_subnet_delete (ifp, ifc); /* Free address information. */ listnode_delete (ifp->connected, ifc); connected_free (ifc); -#endif return CMD_SUCCESS; } +#define IP_ADDR_STR \ + "Interface Internet Protocol config commands\n" \ + "Set the IP address of an interface\n" \ + "IP address (e.g. 10.0.0.1/8)\n" +#define IP_ADDR_PEER_STR \ + "Interface Internet Protocol config commands\n" \ + "Set the IP address of an interface\n" \ + "Local IP (e.g. 10.0.0.1) for P-t-P address\n" \ + "Specify P-t-P address\n" \ + "Peer IP address (e.g. 10.0.0.1/8)\n" + DEFUN (ip_address, ip_address_cmd, "ip address A.B.C.D/M", - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP address (e.g. 10.0.0.1/8)\n") + IP_ADDR_STR) { - return ip_address_install (vty, vty->index, argv[0], NULL, NULL); + return ip_address_install (vty, vty->index, argv[0], NULL, + NULL, NULL, NULL); } DEFUN (no_ip_address, no_ip_address_cmd, "no ip address A.B.C.D/M", - NO_STR - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP Address (e.g. 10.0.0.1/8)") + NO_STR IP_ADDR_STR) { - return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL); + return ip_address_uninstall (vty, vty->index, argv[0], NULL); +} + +DEFUN (ip_address_peer, + ip_address_peer_cmd, + "ip address A.B.C.D peer A.B.C.D/M", + IP_ADDR_PEER_STR) +{ + return ip_address_install (vty, vty->index, argv[0], argv[1], + NULL, NULL, NULL); +} + +DEFUN (no_ip_address_peer, + no_ip_address_peer_cmd, + "no ip address A.B.C.D peer A.B.C.D/M", + NO_STR IP_ADDR_PEER_STR) +{ + return ip_address_uninstall (vty, vty->index, argv[0], argv[1]); } #ifdef HAVE_NETLINK DEFUN (ip_address_label, ip_address_label_cmd, "ip address A.B.C.D/M label LINE", - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP address (e.g. 10.0.0.1/8)\n" + IP_ADDR_STR "Label of this address\n" "Label\n") { - return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]); + return ip_address_install (vty, vty->index, argv[0], NULL, + argv[1], NULL, NULL); } -DEFUN (no_ip_address_label, - no_ip_address_label_cmd, - "no ip address A.B.C.D/M label LINE", - NO_STR - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP address (e.g. 10.0.0.1/8)\n" +DEFUN (ip_address_peer_label, + ip_address_peer_label_cmd, + "ip address A.B.C.D peer A.B.C.D/M label LINE", + IP_ADDR_PEER_STR + "Label of this address\n" + "Label\n") +{ + return ip_address_install (vty, vty->index, argv[0], argv[1], + argv[2], NULL, NULL); +} + +DEFUN (ip_address_scope, + ip_address_scope_cmd, + "ip address A.B.C.D/M scope WORD", + IP_ADDR_STR + "Scope of this address\n" + "Scope (e.g. 0-255 or global,site,link,host,nowhere)\n") +{ + return ip_address_install (vty, vty->index, argv[0], NULL, + NULL, argv[1], NULL); +} + +DEFUN (ip_address_peer_scope, + ip_address_peer_scope_cmd, + "ip address A.B.C.D peer A.B.C.D/M scope WORD", + IP_ADDR_PEER_STR + "Scope of this address\n" + "Scope (e.g. 0-255 or global,site,link,host,nowhere)\n") +{ + return ip_address_install (vty, vty->index, argv[0], argv[1], + NULL, argv[2], NULL); +} + +DEFUN (ip_address_scope_label, + ip_address_scope_label_cmd, + "ip address A.B.C.D/M scope WORD label LINE", + IP_ADDR_STR + "Scope of this address\n" + "Scope (e.g. 0-255 or global,site,link,host,nowhere)\n" "Label of this address\n" "Label\n") { - return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]); + return ip_address_install (vty, vty->index, argv[0], NULL, + argv[2], argv[1], NULL); } + +DEFUN (ip_address_peer_scope_label, + ip_address_peer_scope_label_cmd, + "ip address A.B.C.D peer A.B.C.D/M scope WORD label LINE", + IP_ADDR_PEER_STR + "Scope of this address\n" + "Scope (e.g. 0-255 or global,site,link,host,nowhere)\n" + "Label of this address\n" + "Label\n") +{ + return ip_address_install (vty, vty->index, argv[0], argv[1], + argv[3], argv[2], NULL); +} + #endif /* HAVE_NETLINK */ +#ifdef SIOCSIFADDRPREF +DEFUN (ip_address_pref, + ip_address_pref_cmd, + "ip address A.B.C.D/M preference WORD", + IP_ADDR_STR + "specify IPSRCSEL preference\n" + "preference value, higher is preferred\n") +{ + return ip_address_install (vty, vty->index, argv[0], NULL, + NULL, NULL, argv[1]); +} + +DEFUN (ip_address_peer_pref, + ip_address_peer_pref_cmd, + "ip address A.B.C.D peer A.B.C.D/M preference WORD", + IP_ADDR_PEER_STR + "specify IPSRCSEL preference\n" + "preference value, higher is preferred\n") +{ + return ip_address_install (vty, vty->index, argv[0], argv[1], + NULL, NULL, argv[2]); +} +#endif + #ifdef HAVE_IPV6 static int ipv6_address_install (struct vty *vty, struct interface *ifp, @@ -1590,14 +1777,27 @@ if_config_write (struct vty *vty) { char buf[INET6_ADDRSTRLEN]; p = ifc->address; - vty_out (vty, " ip%s address %s/%d", + vty_out (vty, " ip%s address %s", p->family == AF_INET ? "" : "v6", - inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)), - p->prefixlen); + inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf))); + if (CONNECTED_PEER (ifc)) + { + p = ifc->destination; + vty_out (vty, " peer %s", + inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf))); + } + vty_out (vty, "/%d", p->prefixlen); +#ifdef HAVE_NETLINK + if (ifc->scope) + vty_out (vty, " scope %s", connected_scope_name (ifc->scope)); if (ifc->label) vty_out (vty, " label %s", ifc->label); - +#endif +#ifdef SIOCSIFADDRPREF + if (ifc->preference) + vty_out (vty, " preference %d", ifc->preference); +#endif vty_out (vty, "%s", VTY_NEWLINE); } } @@ -1659,12 +1859,22 @@ zebra_if_init (void) install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd); install_element (INTERFACE_NODE, &ip_address_cmd); install_element (INTERFACE_NODE, &no_ip_address_cmd); + install_element (INTERFACE_NODE, &ip_address_peer_cmd); + install_element (INTERFACE_NODE, &no_ip_address_peer_cmd); #ifdef HAVE_IPV6 install_element (INTERFACE_NODE, &ipv6_address_cmd); install_element (INTERFACE_NODE, &no_ipv6_address_cmd); #endif /* HAVE_IPV6 */ #ifdef HAVE_NETLINK install_element (INTERFACE_NODE, &ip_address_label_cmd); - install_element (INTERFACE_NODE, &no_ip_address_label_cmd); + install_element (INTERFACE_NODE, &ip_address_scope_cmd); + install_element (INTERFACE_NODE, &ip_address_scope_label_cmd); + install_element (INTERFACE_NODE, &ip_address_peer_label_cmd); + install_element (INTERFACE_NODE, &ip_address_peer_scope_cmd); + install_element (INTERFACE_NODE, &ip_address_peer_scope_label_cmd); #endif /* HAVE_NETLINK */ +#ifdef SIOCSIFADDRPREF + install_element (INTERFACE_NODE, &ip_address_pref_cmd); + install_element (INTERFACE_NODE, &ip_address_peer_pref_cmd); +#endif } |