diff options
| author | Mark Stapp <mjs@voltanet.io> | 2021-06-16 16:01:29 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-16 16:01:29 -0400 |
| commit | 368bda4acb82cca90e5dc1021a8aff9ebb1a2b54 (patch) | |
| tree | d5b9b9bb80b4961b9e02bed7e7b5ee85c5008d76 /ospf6d/ospf6_interface.c | |
| parent | 0aeb45c72d3c344ccff54069324f4783ade8483d (diff) | |
| parent | 2cfc32723763630da4a3bc38363cffe1c4b46d08 (diff) | |
Merge pull request #8827 from idryzhov/8.0-backports-06-10
8.0 backports
Diffstat (limited to 'ospf6d/ospf6_interface.c')
| -rw-r--r-- | ospf6d/ospf6_interface.c | 187 |
1 files changed, 156 insertions, 31 deletions
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 9a738aa5b5..8f105f32b9 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -36,6 +36,7 @@ #include "ospf6_message.h" #include "ospf6_route.h" #include "ospf6_area.h" +#include "ospf6_abr.h" #include "ospf6_interface.h" #include "ospf6_neighbor.h" #include "ospf6_intra.h" @@ -109,7 +110,7 @@ static uint8_t ospf6_default_iftype(struct interface *ifp) { if (if_is_pointopoint(ifp)) return OSPF_IFTYPE_POINTOPOINT; - else if (if_is_loopback(ifp)) + else if (if_is_loopback_or_vrf(ifp)) return OSPF_IFTYPE_LOOPBACK; else return OSPF_IFTYPE_BROADCAST; @@ -330,31 +331,6 @@ ospf6_interface_get_linklocal_address(struct interface *ifp) return l; } -void ospf6_interface_if_add(struct interface *ifp) -{ - struct ospf6_interface *oi; - unsigned int iobuflen; - - oi = (struct ospf6_interface *)ifp->info; - if (oi == NULL) - return; - - /* Try to adjust I/O buffer size with IfMtu */ - if (oi->ifmtu == 0) - oi->ifmtu = ifp->mtu6; - iobuflen = ospf6_iobuf_size(ifp->mtu6); - if (oi->ifmtu > iobuflen) { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug( - "Interface %s: IfMtu is adjusted to I/O buffer size: %d.", - ifp->name, iobuflen); - oi->ifmtu = iobuflen; - } - - /* interface start */ - ospf6_interface_state_update(oi->interface); -} - void ospf6_interface_state_update(struct interface *ifp) { struct ospf6_interface *oi; @@ -390,7 +366,7 @@ void ospf6_interface_state_update(struct interface *ifp) if (if_is_operative(ifp) && (ospf6_interface_get_linklocal_address(oi->interface) - || if_is_loopback(oi->interface))) + || if_is_loopback_or_vrf(oi->interface))) thread_execute(master, interface_up, oi, 0); else thread_execute(master, interface_down, oi, 0); @@ -734,7 +710,7 @@ int interface_up(struct thread *thread) /* check interface has a link-local address */ if (!(ospf6_interface_get_linklocal_address(oi->interface) - || if_is_loopback(oi->interface))) { + || if_is_loopback_or_vrf(oi->interface))) { if (IS_OSPF6_DEBUG_INTERFACE) zlog_debug( "Interface %s has no link local address, can't execute [InterfaceUp]", @@ -800,7 +776,7 @@ int interface_up(struct thread *thread) /* Schedule Hello */ if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE) - && !if_is_loopback(oi->interface)) { + && !if_is_loopback_or_vrf(oi->interface)) { oi->thread_send_hello = NULL; thread_add_event(master, ospf6_hello_send, oi, 0, &oi->thread_send_hello); @@ -1618,7 +1594,143 @@ DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd, return CMD_SUCCESS; } +void ospf6_interface_start(struct ospf6_interface *oi) +{ + struct ospf6 *ospf6; + struct ospf6_area *oa; + + if (oi->area_id_format == OSPF6_AREA_FMT_UNSET) + return; + + ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id); + if (!ospf6) + return; + + oa = ospf6_area_lookup(oi->area_id, ospf6); + if (oa == NULL) + oa = ospf6_area_create(oi->area_id, ospf6, oi->area_id_format); + + /* attach interface to area */ + listnode_add(oa->if_list, oi); + oi->area = oa; + + SET_FLAG(oa->flag, OSPF6_AREA_ENABLE); + + /* start up */ + ospf6_interface_enable(oi); + + /* If the router is ABR, originate summary routes */ + if (ospf6_is_router_abr(ospf6)) + ospf6_abr_enable_area(oa); +} + +void ospf6_interface_stop(struct ospf6_interface *oi) +{ + struct ospf6_area *oa; + + oa = oi->area; + if (!oa) + return; + + ospf6_interface_disable(oi); + + listnode_delete(oa->if_list, oi); + oi->area = NULL; + + if (oa->if_list->count == 0) { + UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE); + ospf6_abr_disable_area(oa); + } +} + /* interface variable set command */ +DEFUN (ipv6_ospf6_area, + ipv6_ospf6_area_cmd, + "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>", + IP6_STR + OSPF6_STR + "Specify the OSPF6 area ID\n" + "OSPF6 area ID in IPv4 address notation\n" + "OSPF6 area ID in decimal notation\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + int idx_ipv4 = 3; + uint32_t area_id; + int format; + int ipv6_count = 0; + + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + if (oi->area) { + vty_out(vty, "%s already attached to Area %s\n", + oi->interface->name, oi->area->name); + return CMD_SUCCESS; + } + + /* if more than OSPF6_MAX_IF_ADDRS are configured on this interface + * then don't allow ospfv3 to be configured + */ + ipv6_count = connected_count_by_family(ifp, AF_INET6); + if (oi->ifmtu == OSPF6_DEFAULT_MTU && ipv6_count > OSPF6_MAX_IF_ADDRS) { + vty_out(vty, + "can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n", + ifp->name, OSPF6_MAX_IF_ADDRS, ipv6_count); + return CMD_WARNING_CONFIG_FAILED; + } else if (oi->ifmtu >= OSPF6_JUMBO_MTU + && ipv6_count > OSPF6_MAX_IF_ADDRS_JUMBO) { + vty_out(vty, + "can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n", + ifp->name, OSPF6_MAX_IF_ADDRS_JUMBO, ipv6_count); + return CMD_WARNING_CONFIG_FAILED; + } + + if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) { + vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + oi->area_id = area_id; + oi->area_id_format = format; + + ospf6_interface_start(oi); + + return CMD_SUCCESS; +} + +DEFUN (no_ipv6_ospf6_area, + no_ipv6_ospf6_area_cmd, + "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]", + NO_STR + IP6_STR + OSPF6_STR + "Specify the OSPF6 area ID\n" + "OSPF6 area ID in IPv4 address notation\n" + "OSPF6 area ID in decimal notation\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + ospf6_interface_stop(oi); + + oi->area_id = 0; + oi->area_id_format = OSPF6_AREA_FMT_UNSET; + + return CMD_SUCCESS; +} + DEFUN (ipv6_ospf6_ifmtu, ipv6_ospf6_ifmtu_cmd, "ipv6 ospf6 ifmtu (1-65535)", @@ -2106,7 +2218,7 @@ DEFUN (no_ipv6_ospf6_passive, THREAD_OFF(oi->thread_sso); /* don't send hellos over loopback interface */ - if (!if_is_loopback(oi->interface)) + if (!if_is_loopback_or_vrf(oi->interface)) thread_add_event(master, ospf6_hello_send, oi, 0, &oi->thread_send_hello); @@ -2314,6 +2426,7 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf) { struct ospf6_interface *oi; struct interface *ifp; + char buf[INET_ADDRSTRLEN]; FOR_ALL_INTERFACES (vrf, ifp) { oi = (struct ospf6_interface *)ifp->info; @@ -2328,6 +2441,11 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf) if (ifp->desc) vty_out(vty, " description %s\n", ifp->desc); + if (oi->area_id_format != OSPF6_AREA_FMT_UNSET) { + area_id2str(buf, sizeof(buf), oi->area_id, + oi->area_id_format); + vty_out(vty, " ipv6 ospf6 area %s\n", buf); + } if (oi->c_ifmtu) vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu); @@ -2407,7 +2525,9 @@ static int ospf6_ifp_create(struct interface *ifp) if (IS_OSPF6_DEBUG_ZEBRA(RECV)) zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name, ifp->ifindex, ifp->mtu6); - ospf6_interface_if_add(ifp); + + if (ifp->info) + ospf6_interface_start(ifp->info); return 0; } @@ -2448,6 +2568,9 @@ static int ospf6_ifp_destroy(struct interface *ifp) zlog_debug("Zebra Interface delete: %s index %d mtu %d", ifp->name, ifp->ifindex, ifp->mtu6); + if (ifp->info) + ospf6_interface_stop(ifp->info); + return 0; } @@ -2465,6 +2588,8 @@ void ospf6_interface_init(void) &show_ipv6_ospf6_interface_ifname_prefix_cmd); install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_area_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_area_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd); |
