diff options
Diffstat (limited to 'ospfd/ospf_packet.c')
| -rw-r--r-- | ospfd/ospf_packet.c | 88 |
1 files changed, 60 insertions, 28 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 36f9a6757a..47f5ee76d2 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -519,7 +519,7 @@ int ospf_ls_upd_timer(struct thread *thread) if (listcount(update) > 0) ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT); - list_delete(update); + list_delete_and_null(&update); } /* Set LS Update retransmission timer. */ @@ -649,6 +649,12 @@ static int ospf_write(struct thread *thread) #define OSPF_WRITE_IPHL_SHIFT 2 int pkt_count = 0; +#ifdef GNU_LINUX + unsigned char cmsgbuf[64] = {}; + struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf; + struct in_pktinfo *pi; +#endif + ospf->t_write = NULL; node = listhead(ospf->oi_write_q); @@ -753,14 +759,28 @@ static int ospf_write(struct thread *thread) msg.msg_namelen = sizeof(sa_dst); msg.msg_iov = iov; msg.msg_iovlen = 2; + iov[0].iov_base = (char *)&iph; iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT; iov[1].iov_base = STREAM_PNT(op->s); iov[1].iov_len = op->length; -/* Sadly we can not rely on kernels to fragment packets because of either - * IP_HDRINCL and/or multicast destination being set. - */ +#ifdef GNU_LINUX + msg.msg_control = (caddr_t)cm; + cm->cmsg_level = SOL_IP; + cm->cmsg_type = IP_PKTINFO; + cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + pi = (struct in_pktinfo *)CMSG_DATA(cm); + pi->ipi_ifindex = oi->ifp->ifindex; + + msg.msg_controllen = cm->cmsg_len; +#endif + + /* Sadly we can not rely on kernels to fragment packets + * because of either IP_HDRINCL and/or multicast + * destination being set. + */ + #ifdef WANT_OSPF_WRITE_FRAGMENT if (op->length > maxdatasize) ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize, @@ -907,9 +927,10 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Packet %s [Hello:RECV]: Options %s", + zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s", inet_ntoa(ospfh->router_id), - ospf_options_dump(hello->options)); + ospf_options_dump(hello->options), + ospf_vrf_id_to_name(oi->ospf->vrf_id)); /* Compare options. */ #define REJECT_IF_TBIT_ON 1 /* XXX */ @@ -1551,15 +1572,16 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, /* Verify LSA type. */ if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA) { OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); - list_delete(ls_upd); + list_delete_and_null(&ls_upd); return; } /* Search proper LSA in LSDB. */ - find = ospf_lsa_lookup(oi->area, ls_type, ls_id, adv_router); + find = ospf_lsa_lookup(oi->ospf, oi->area, ls_type, ls_id, + adv_router); if (find == NULL) { OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); - list_delete(ls_upd); + list_delete_and_null(&ls_upd); return; } @@ -1593,9 +1615,9 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT); - list_delete(ls_upd); + list_delete_and_null(&ls_upd); } else - list_free(ls_upd); + list_delete_and_null(&ls_upd); } /* Get the list of LSAs from Link State Update packet. @@ -1696,6 +1718,7 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, /* Create OSPF LSA instance. */ lsa = ospf_lsa_new(); + lsa->vrf_id = oi->ospf->vrf_id; /* We may wish to put some error checking if type NSSA comes in and area not in NSSA mode */ switch (lsah->type) { @@ -1735,7 +1758,7 @@ static void ospf_upd_list_clean(struct list *lsas) for (ALL_LIST_ELEMENTS(lsas, node, nnode, lsa)) ospf_lsa_discard(lsa); - list_delete(lsas); + list_delete_and_null(&lsas); } /* OSPF Link State Update message read -- RFC2328 Section 13. */ @@ -1784,6 +1807,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, */ lsas = ospf_ls_upd_list_lsa(nbr, s, oi, size); + if (lsas == NULL) + return; #define DISCARD_LSA(L, N) \ { \ if (IS_DEBUG_OSPF_EVENT) \ @@ -2134,7 +2159,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, #undef DISCARD_LSA assert(listcount(lsas) == 0); - list_delete(lsas); + list_delete_and_null(&lsas); } /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */ @@ -2173,6 +2198,7 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, lsa = ospf_lsa_new(); lsa->data = (struct lsa_header *)STREAM_PNT(s); + lsa->vrf_id = oi->ospf->vrf_id; /* lsah = (struct lsa_header *) STREAM_PNT (s); */ size -= OSPF_LSA_HEADER_SIZE; @@ -2197,7 +2223,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, return; } -static struct stream *ospf_recv_packet(int fd, struct interface **ifp, +static struct stream *ospf_recv_packet(struct ospf *ospf, int fd, + struct interface **ifp, struct stream *ibuf) { int ret; @@ -2265,7 +2292,7 @@ static struct stream *ospf_recv_packet(int fd, struct interface **ifp, ifindex = getsockopt_ifindex(AF_INET, &msgh); - *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); + *ifp = if_lookup_by_index(ifindex, ospf->vrf_id); if (ret != ip_len) { zlog_warn( @@ -2833,7 +2860,7 @@ int ospf_read(struct thread *thread) struct ip *iph; struct ospf_header *ospfh; u_int16_t length; - struct interface *ifp; + struct interface *ifp = NULL; struct connected *c; /* first of all get interface pointer. */ @@ -2844,7 +2871,8 @@ int ospf_read(struct thread *thread) thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read); stream_reset(ospf->ibuf); - if (!(ibuf = ospf_recv_packet(ospf->fd, &ifp, ospf->ibuf))) + ibuf = ospf_recv_packet(ospf, ospf->fd, &ifp, ospf->ibuf); + if (ibuf == NULL) return -1; /* This raw packet is known to be at least as big as its IP header. */ @@ -2861,7 +2889,7 @@ int ospf_read(struct thread *thread) ifindex retrieval but do not. */ c = if_lookup_address((void *)&iph->ip_src, AF_INET, - VRF_DEFAULT); + ospf->vrf_id); if (c) ifp = c->ifp; if (ifp == NULL) @@ -3487,6 +3515,13 @@ static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr) op->dst.s_addr = addr; + if (IS_DEBUG_OSPF_EVENT) { + if (oi->ospf->vrf_id) + zlog_debug("%s: Hello Tx interface %s ospf vrf %s id %u", + __PRETTY_FUNCTION__, oi->ifp->name, + ospf_vrf_id_to_name(oi->ospf->vrf_id), + oi->ospf->vrf_id); + } /* Add packet to the top of the interface output queue, so that they * can't get delayed by things like long queues of LS Update packets */ @@ -3739,7 +3774,7 @@ void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa, listnode_add(update, lsa); ospf_ls_upd_send(nbr, update, flag); - list_delete(update); + list_delete_and_null(&update); } /* Determine size for packet. Must be at least big enough to accomodate next @@ -3883,8 +3918,7 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread) /* list might not be empty. */ if (listcount(update) == 0) { - list_delete(rn->info); - rn->info = NULL; + list_delete_and_null((struct list **)&rn->info); route_unlock_node(rn); } else again = 1; @@ -4065,21 +4099,19 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi) * punt-to-CPU set on them. This may overload the CPU control path that * can be avoided if the MAC was known apriori. */ -#define OSPF_PING_NBR_STR_MAX (8 + 40 + 20) +#define OSPF_PING_NBR_STR_MAX (BUFSIZ) void ospf_proactively_arp(struct ospf_neighbor *nbr) { char ping_nbr[OSPF_PING_NBR_STR_MAX]; - char *str_ptr; int ret; if (!nbr || !nbr->oi || !nbr->oi->ifp) return; - str_ptr = strcpy(ping_nbr, "ping -c 1 -I "); - str_ptr = strcat(str_ptr, nbr->oi->ifp->name); - str_ptr = strcat(str_ptr, " "); - str_ptr = strcat(str_ptr, inet_ntoa(nbr->address.u.prefix4)); - str_ptr = strcat(str_ptr, " > /dev/null 2>&1 &"); + snprintf(ping_nbr, sizeof(ping_nbr), + "ping -c 1 -I %s %s > /dev/null 2>&1 &", + nbr->oi->ifp->name, inet_ntoa(nbr->address.u.prefix4)); + ret = system(ping_nbr); if (IS_DEBUG_OSPF_EVENT) zlog_debug("Executed %s %s", ping_nbr, |
