diff options
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_interface.c | 3 | ||||
-rw-r--r-- | ospfd/ospf_interface.h | 1 | ||||
-rw-r--r-- | ospfd/ospf_snmp.c | 26 | ||||
-rw-r--r-- | ospfd/ospf_te.c | 63 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 39 |
5 files changed, 94 insertions, 38 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 0969ae1..173dafb 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -1373,7 +1373,8 @@ static int ospf_ifp_create(struct interface *ifp) (!OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type) || if_is_loopback(ifp))) { SET_IF_PARAM(IF_DEF_PARAMS(ifp), type); - IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); + if (!IF_DEF_PARAMS(ifp)->type_cfg) + IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); } ospf = ifp->vrf->info; diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 08a2b11..39dc951 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -57,6 +57,7 @@ struct ospf_if_params { DECLARE_IF_PARAM(struct in_addr, if_area); uint32_t if_area_id_fmt; + bool type_cfg; DECLARE_IF_PARAM(uint8_t, type); /* type of interface */ #define OSPF_IF_ACTIVE 0 #define OSPF_IF_PASSIVE 1 diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index fc0c143..4e1f153 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -906,7 +906,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, area = ospf_area_lookup_by_area_id(ospf, *area_id); if (!area) return NULL; - offset++; + offset += IN_ADDR_SIZE; /* Type. */ *type = *offset; @@ -914,7 +914,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, /* LS ID. */ oid2in_addr(offset, IN_ADDR_SIZE, ls_id); - offset++; + offset += IN_ADDR_SIZE; /* Router ID. */ oid2in_addr(offset, IN_ADDR_SIZE, router_id); @@ -971,7 +971,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, } /* Router ID. */ - offset++; + offset += IN_ADDR_SIZE; offsetlen -= IN_ADDR_SIZE; len = offsetlen; @@ -996,11 +996,11 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, /* Fill in value. */ offset = name + v->namelen; oid_copy_in_addr(offset, area_id); - offset++; + offset += IN_ADDR_SIZE; *offset = lsa->data->type; offset++; oid_copy_in_addr(offset, &lsa->data->id); - offset++; + offset += IN_ADDR_SIZE; oid_copy_in_addr(offset, &lsa->data->adv_router); @@ -1106,7 +1106,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, if (!area) return NULL; - offset++; + offset += IN_ADDR_SIZE; /* Lookup area range. */ oid2in_addr(offset, IN_ADDR_SIZE, range_net); @@ -1135,7 +1135,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, return NULL; do { - offset++; + offset += IN_ADDR_SIZE; offsetlen -= IN_ADDR_SIZE; len = offsetlen; @@ -1157,7 +1157,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, /* Fill in value. */ offset = name + v->namelen; oid_copy_in_addr(offset, area_id); - offset++; + offset += IN_ADDR_SIZE; oid_copy_in_addr(offset, range_net); return range; @@ -1559,7 +1559,7 @@ static struct ospf_interface *ospfIfLookup(struct variable *v, oid *name, *length = v->namelen + IN_ADDR_SIZE + 1; offset = name + v->namelen; oid_copy_in_addr(offset, ifaddr); - offset++; + offset += IN_ADDR_SIZE; *offset = *ifindex; return oi; } @@ -1703,7 +1703,7 @@ static struct ospf_interface *ospfIfMetricLookup(struct variable *v, oid *name, *length = v->namelen + IN_ADDR_SIZE + 1 + 1; offset = name + v->namelen; oid_copy_in_addr(offset, ifaddr); - offset++; + offset += IN_ADDR_SIZE; *offset = *ifindex; offset++; *offset = OSPF_SNMP_METRIC_VALUE; @@ -2241,7 +2241,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, /* LS ID. */ oid2in_addr(offset, IN_ADDR_SIZE, ls_id); - offset++; + offset += IN_ADDR_SIZE; /* Router ID. */ oid2in_addr(offset, IN_ADDR_SIZE, router_id); @@ -2269,7 +2269,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, oid2in_addr(offset, len, ls_id); - offset++; + offset += IN_ADDR_SIZE; offsetlen -= IN_ADDR_SIZE; /* Router ID. */ @@ -2292,7 +2292,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, *offset = OSPF_AS_EXTERNAL_LSA; offset++; oid_copy_in_addr(offset, &lsa->data->id); - offset++; + offset += IN_ADDR_SIZE; oid_copy_in_addr(offset, &lsa->data->adv_router); return lsa; diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 80ebab3..b1563b5 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -1670,6 +1670,11 @@ static struct ls_edge *get_edge(struct ls_ted *ted, struct ls_node_id adv, struct ls_edge *edge; struct ls_attributes *attr; + /* Check that Link ID and Node ID are valid */ + if (IPV4_NET0(link_id.s_addr) || IPV4_NET0(adv.id.ip.addr.s_addr) || + adv.origin != OSPFv2) + return NULL; + /* Search Edge that corresponds to the Link ID */ key.family = AF_INET; IPV4_ADDR_COPY(&key.k.addr, &link_id); @@ -1743,6 +1748,10 @@ static void ospf_te_update_link(struct ls_ted *ted, struct ls_vertex *vertex, /* Get Corresponding Edge from Link State Data Base */ edge = get_edge(ted, vertex->node->adv, link_data); + if (!edge) { + ote_debug(" |- Found no edge from Link Data. Abort!"); + return; + } attr = edge->attributes; /* re-attached edge to vertex if needed */ @@ -2246,11 +2255,11 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa) } /* Get corresponding Edge from Link State Data Base */ - if (IPV4_NET0(attr.standard.local.s_addr) && !attr.standard.local_id) { - ote_debug(" |- Found no TE Link local address/ID. Abort!"); + edge = get_edge(ted, attr.adv, attr.standard.local); + if (!edge) { + ote_debug(" |- Found no edge from Link local add./ID. Abort!"); return -1; } - edge = get_edge(ted, attr.adv, attr.standard.local); old = edge->attributes; ote_debug(" |- Process Traffic Engineering LSA %pI4 for Edge %pI4", @@ -2456,6 +2465,9 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) switch (ntohs(tlvh->type)) { case RI_SR_TLV_SR_ALGORITHM: + if (TLV_BODY_SIZE(tlvh) < 1 || + TLV_BODY_SIZE(tlvh) > ALGORITHM_COUNT) + break; algo = (struct ri_sr_tlv_sr_algorithm *)tlvh; for (int i = 0; i < ntohs(algo->header.length); i++) { @@ -2480,6 +2492,8 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) break; case RI_SR_TLV_SRGB_LABEL_RANGE: + if (TLV_BODY_SIZE(tlvh) != RI_SR_TLV_LABEL_RANGE_SIZE) + break; range = (struct ri_sr_tlv_sid_label_range *)tlvh; size = GET_RANGE_SIZE(ntohl(range->size)); lower = GET_LABEL(ntohl(range->lower.value)); @@ -2497,6 +2511,8 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) break; case RI_SR_TLV_SRLB_LABEL_RANGE: + if (TLV_BODY_SIZE(tlvh) != RI_SR_TLV_LABEL_RANGE_SIZE) + break; range = (struct ri_sr_tlv_sid_label_range *)tlvh; size = GET_RANGE_SIZE(ntohl(range->size)); lower = GET_LABEL(ntohl(range->lower.value)); @@ -2514,6 +2530,8 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) break; case RI_SR_TLV_NODE_MSD: + if (TLV_BODY_SIZE(tlvh) < RI_SR_TLV_NODE_MSD_SIZE) + break; msd = (struct ri_sr_tlv_node_msd *)tlvh; if ((CHECK_FLAG(node->flags, LS_NODE_MSD)) && (node->msd == msd->value)) @@ -2611,6 +2629,7 @@ static int ospf_te_parse_ext_pref(struct ls_ted *ted, struct ospf_lsa *lsa) struct ext_tlv_prefix *ext; struct ext_subtlv_prefix_sid *pref_sid; uint32_t label; + uint16_t len, size; /* Get corresponding Subnet from Link State Data Base */ ext = (struct ext_tlv_prefix *)TLV_HDR_TOP(lsa->data); @@ -2632,6 +2651,18 @@ static int ospf_te_parse_ext_pref(struct ls_ted *ted, struct ospf_lsa *lsa) ote_debug(" |- Process Extended Prefix LSA %pI4 for subnet %pFX", &lsa->data->id, &pref); + /* + * Check Extended Prefix TLV size against LSA size + * as only one TLV is allowed per LSA + */ + len = TLV_BODY_SIZE(&ext->header); + size = lsa->size - (OSPF_LSA_HEADER_SIZE + TLV_HDR_SIZE); + if (len != size || len <= 0) { + ote_debug(" |- Wrong TLV size: %u instead of %u", + (uint32_t)len, (uint32_t)size); + return -1; + } + /* Initialize TLV browsing */ ls_pref = subnet->ls_pref; pref_sid = (struct ext_subtlv_prefix_sid *)((char *)(ext) + TLV_HDR_SIZE @@ -2737,13 +2768,29 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) lnid.id.ip.area_id = lsa->area->area_id; ext = (struct ext_tlv_link *)TLV_HDR_TOP(lsa->data); edge = get_edge(ted, lnid, ext->link_data); + if (!edge) { + ote_debug(" |- Found no edge from Extended Link Data. Abort!"); + return -1; + } atr = edge->attributes; ote_debug(" |- Process Extended Link LSA %pI4 for edge %pI4", &lsa->data->id, &edge->attributes->standard.local); - /* Initialize TLV browsing */ - len = TLV_BODY_SIZE(&ext->header) - EXT_TLV_LINK_SIZE; + /* + * Check Extended Link TLV size against LSA size + * as only one TLV is allowed per LSA + */ + len = TLV_BODY_SIZE(&ext->header); + i = lsa->size - (OSPF_LSA_HEADER_SIZE + TLV_HDR_SIZE); + if (len != i || len <= 0) { + ote_debug(" |- Wrong TLV size: %u instead of %u", + (uint32_t)len, (uint32_t)i); + return -1; + } + + /* Initialize subTLVs browsing */ + len -= EXT_TLV_LINK_SIZE; tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE + EXT_TLV_LINK_SIZE); for (; sum < len; tlvh = TLV_HDR_NEXT(tlvh)) { @@ -2753,6 +2800,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) switch (ntohs(tlvh->type)) { case EXT_SUBTLV_ADJ_SID: + if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_ADJ_SID_SIZE) + break; adj = (struct ext_subtlv_adj_sid *)tlvh; label = CHECK_FLAG(adj->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) @@ -2779,6 +2828,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) break; case EXT_SUBTLV_LAN_ADJ_SID: + if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_LAN_ADJ_SID_SIZE) + break; ladj = (struct ext_subtlv_lan_adj_sid *)tlvh; label = CHECK_FLAG(ladj->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) @@ -2808,6 +2859,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) break; case EXT_SUBTLV_RMT_ITF_ADDR: + if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_RMT_ITF_ADDR_SIZE) + break; rmt = (struct ext_subtlv_rmt_itf_addr *)tlvh; if (CHECK_FLAG(atr->flags, LS_ATTR_NEIGH_ADDR) && IPV4_ADDR_SAME(&atr->standard.remote, diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 93dd12c..4f30d52 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -8267,6 +8267,8 @@ static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str, ospf_nbr_timer_update(oi); } + if (params->fast_hello != OSPF_FAST_HELLO_DEFAULT) + ospf_reset_hello_timer(ifp, addr, false); return CMD_SUCCESS; } @@ -8591,6 +8593,8 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd, IF_DEF_PARAMS(ifp)->ptp_dmvpn = 1; } + IF_DEF_PARAMS(ifp)->type_cfg = true; + if (IF_DEF_PARAMS(ifp)->type == old_type && IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn && IF_DEF_PARAMS(ifp)->p2mp_delay_reflood == old_p2mp_delay_reflood) @@ -8654,6 +8658,7 @@ DEFUN (no_ip_ospf_network, struct route_node *rn; IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); + IF_DEF_PARAMS(ifp)->type_cfg = false; IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0; IF_DEF_PARAMS(ifp)->p2mp_delay_reflood = OSPF_P2MP_DELAY_REFLOOD_DEFAULT; @@ -12211,25 +12216,21 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) do { /* Interface Network print. */ - if (OSPF_IF_PARAM_CONFIGURED(params, type) - && params->type != OSPF_IFTYPE_LOOPBACK) { - if (params->type != ospf_default_iftype(ifp)) { - vty_out(vty, " ip ospf network %s", - ospf_int_type_str - [params->type]); - if (params->type - == OSPF_IFTYPE_POINTOPOINT - && params->ptp_dmvpn) - vty_out(vty, " dmvpn"); - if (params->type == - OSPF_IFTYPE_POINTOMULTIPOINT && - params->p2mp_delay_reflood) - vty_out(vty, " delay-reflood"); - if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %pI4", - &rn->p.u.prefix4); - vty_out(vty, "\n"); - } + if (OSPF_IF_PARAM_CONFIGURED(params, type) && + params->type != OSPF_IFTYPE_LOOPBACK && + params->type_cfg) { + vty_out(vty, " ip ospf network %s", + ospf_int_type_str[params->type]); + if (params->type == OSPF_IFTYPE_POINTOPOINT && + params->ptp_dmvpn) + vty_out(vty, " dmvpn"); + if (params->type == + OSPF_IFTYPE_POINTOMULTIPOINT && + params->p2mp_delay_reflood) + vty_out(vty, " delay-reflood"); + if (params != IF_DEF_PARAMS(ifp) && rn) + vty_out(vty, " %pI4", &rn->p.u.prefix4); + vty_out(vty, "\n"); } /* OSPF interface authentication print */ |