summaryrefslogtreecommitdiffstats
path: root/ospfd
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ospfd/ospf_interface.c3
-rw-r--r--ospfd/ospf_interface.h1
-rw-r--r--ospfd/ospf_snmp.c26
-rw-r--r--ospfd/ospf_te.c63
-rw-r--r--ospfd/ospf_vty.c39
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 */