mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 19:35:13 +00:00
Merge pull request #10677 from mobash-rasool/pimv6-receive-pkt
pim6d: Handling of receiving of PIMv6 packets
This commit is contained in:
commit
5bc17d7bd0
@ -1271,7 +1271,7 @@ static bool pim_bsm_parse_install_g2rp(struct bsm_scope *scope, uint8_t *buf,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
|
int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
|
||||||
uint32_t buf_size, bool no_fwd)
|
uint32_t buf_size, bool no_fwd)
|
||||||
{
|
{
|
||||||
struct bsm_hdr *bshdr;
|
struct bsm_hdr *bshdr;
|
||||||
@ -1371,7 +1371,7 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if PIM_IPV == 4
|
#if PIM_IPV == 4
|
||||||
if (ip_hdr->ip_dst.s_addr == qpim_all_pim_routers_addr.s_addr)
|
if (!pim_addr_cmp(sg->grp, qpim_all_pim_routers_addr))
|
||||||
#else
|
#else
|
||||||
if (0)
|
if (0)
|
||||||
#endif
|
#endif
|
||||||
@ -1380,18 +1380,16 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
|
|||||||
* match RPF towards the BSR's IP address, or they have
|
* match RPF towards the BSR's IP address, or they have
|
||||||
* no-forward set
|
* no-forward set
|
||||||
*/
|
*/
|
||||||
if (!no_fwd
|
if (!no_fwd && !pim_nht_bsr_rpf_check(pim, bshdr->bsr_addr.addr,
|
||||||
&& !pim_nht_bsr_rpf_check(pim, bshdr->bsr_addr.addr, ifp,
|
ifp, sg->src)) {
|
||||||
ip_hdr->ip_src)) {
|
|
||||||
if (PIM_DEBUG_BSM)
|
if (PIM_DEBUG_BSM)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"BSM check: RPF to BSR %s is not %pI4%%%s",
|
"BSM check: RPF to BSR %s is not %pPA%%%s",
|
||||||
bsr_str, &ip_hdr->ip_src, ifp->name);
|
bsr_str, &sg->src, ifp->name);
|
||||||
pim->bsm_dropped++;
|
pim->bsm_dropped++;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (if_address_is_local(&ip_hdr->ip_dst, AF_INET,
|
} else if (if_address_is_local(&sg->grp, PIM_AF, pim->vrf->vrf_id)) {
|
||||||
pim->vrf->vrf_id)) {
|
|
||||||
/* Unicast BSM received - if ucast bsm not enabled on
|
/* Unicast BSM received - if ucast bsm not enabled on
|
||||||
* the interface, drop it
|
* the interface, drop it
|
||||||
*/
|
*/
|
||||||
|
@ -207,11 +207,8 @@ void pim_bsm_proc_init(struct pim_instance *pim);
|
|||||||
void pim_bsm_proc_free(struct pim_instance *pim);
|
void pim_bsm_proc_free(struct pim_instance *pim);
|
||||||
void pim_bsm_clear(struct pim_instance *pim);
|
void pim_bsm_clear(struct pim_instance *pim);
|
||||||
void pim_bsm_write_config(struct vty *vty, struct interface *ifp);
|
void pim_bsm_write_config(struct vty *vty, struct interface *ifp);
|
||||||
int pim_bsm_process(struct interface *ifp,
|
int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
|
||||||
struct ip *ip_hdr,
|
uint32_t buf_size, bool no_fwd);
|
||||||
uint8_t *buf,
|
|
||||||
uint32_t buf_size,
|
|
||||||
bool no_fwd);
|
|
||||||
bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp);
|
bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp);
|
||||||
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
|
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
|
||||||
struct prefix *grp);
|
struct prefix *grp);
|
||||||
|
@ -279,7 +279,7 @@ void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
|
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
|
||||||
struct interface *src_ifp, struct in_addr src_ip)
|
struct interface *src_ifp, pim_addr src_ip)
|
||||||
{
|
{
|
||||||
struct pim_nexthop_cache *pnc = NULL;
|
struct pim_nexthop_cache *pnc = NULL;
|
||||||
struct pim_nexthop_cache lookup;
|
struct pim_nexthop_cache lookup;
|
||||||
|
@ -76,6 +76,6 @@ void pim_nht_bsr_add(struct pim_instance *pim, struct in_addr bsr_addr);
|
|||||||
void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr bsr_addr);
|
void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr bsr_addr);
|
||||||
/* RPF(bsr_addr) == src_ip%src_ifp? */
|
/* RPF(bsr_addr) == src_ip%src_ifp? */
|
||||||
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
|
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
|
||||||
struct interface *src_ifp, struct in_addr src_ip);
|
struct interface *src_ifp, pim_addr src_ip);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -138,31 +138,33 @@ void pim_sock_delete(struct interface *ifp, const char *delete_message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* For now check dst address for hello, assrt and join/prune is all pim rtr */
|
/* For now check dst address for hello, assrt and join/prune is all pim rtr */
|
||||||
static bool pim_pkt_dst_addr_ok(enum pim_msg_type type, in_addr_t addr)
|
static bool pim_pkt_dst_addr_ok(enum pim_msg_type type, pim_addr addr)
|
||||||
{
|
{
|
||||||
if ((type == PIM_MSG_TYPE_HELLO) || (type == PIM_MSG_TYPE_ASSERT)
|
if ((type == PIM_MSG_TYPE_HELLO) || (type == PIM_MSG_TYPE_ASSERT)
|
||||||
|| (type == PIM_MSG_TYPE_JOIN_PRUNE)) {
|
|| (type == PIM_MSG_TYPE_JOIN_PRUNE)) {
|
||||||
if (addr != qpim_all_pim_routers_addr.s_addr)
|
if (pim_addr_cmp(addr, qpim_all_pim_routers_addr))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
|
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len,
|
||||||
|
pim_sgaddr sg)
|
||||||
{
|
{
|
||||||
struct ip *ip_hdr;
|
#if PIM_IPV == 4
|
||||||
|
struct ip *ip_hdr = (struct ip *)buf;
|
||||||
size_t ip_hlen; /* ip header length in bytes */
|
size_t ip_hlen; /* ip header length in bytes */
|
||||||
char src_str[INET_ADDRSTRLEN];
|
#endif
|
||||||
char dst_str[INET_ADDRSTRLEN];
|
|
||||||
uint8_t *pim_msg;
|
uint8_t *pim_msg;
|
||||||
int pim_msg_len;
|
uint32_t pim_msg_len = 0;
|
||||||
uint16_t pim_checksum; /* received checksum */
|
uint16_t pim_checksum; /* received checksum */
|
||||||
uint16_t checksum; /* computed checksum */
|
uint16_t checksum; /* computed checksum */
|
||||||
struct pim_neighbor *neigh;
|
struct pim_neighbor *neigh;
|
||||||
struct pim_msg_header *header;
|
struct pim_msg_header *header;
|
||||||
bool no_fwd;
|
bool no_fwd;
|
||||||
|
|
||||||
|
#if PIM_IPV == 4
|
||||||
if (len < sizeof(*ip_hdr)) {
|
if (len < sizeof(*ip_hdr)) {
|
||||||
if (PIM_DEBUG_PIM_PACKETS)
|
if (PIM_DEBUG_PIM_PACKETS)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -171,11 +173,16 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_hdr = (struct ip *)buf;
|
|
||||||
ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
|
ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
|
||||||
|
sg = pim_sgaddr_from_iphdr(ip_hdr);
|
||||||
|
|
||||||
pim_msg = buf + ip_hlen;
|
pim_msg = buf + ip_hlen;
|
||||||
pim_msg_len = len - ip_hlen;
|
pim_msg_len = len - ip_hlen;
|
||||||
|
#else
|
||||||
|
/* NB: header is not included in IPv6 RX */
|
||||||
|
pim_msg = buf;
|
||||||
|
pim_msg_len = len;
|
||||||
|
#endif
|
||||||
|
|
||||||
header = (struct pim_msg_header *)pim_msg;
|
header = (struct pim_msg_header *)pim_msg;
|
||||||
if (pim_msg_len < PIM_PIM_MIN_LEN) {
|
if (pim_msg_len < PIM_PIM_MIN_LEN) {
|
||||||
@ -235,43 +242,29 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_PACKETS) {
|
if (PIM_DEBUG_PIM_PACKETS) {
|
||||||
pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str,
|
|
||||||
sizeof(src_str));
|
|
||||||
pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str,
|
|
||||||
sizeof(dst_str));
|
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"Recv PIM %s packet from %s to %s on %s: ttl=%d pim_version=%d pim_msg_size=%d checksum=%x",
|
"Recv PIM %s packet from %pPA to %pPA on %s: pim_version=%d pim_msg_size=%d checksum=%x",
|
||||||
pim_pim_msgtype2str(header->type), src_str, dst_str,
|
pim_pim_msgtype2str(header->type), &sg.src, &sg.grp,
|
||||||
ifp->name, ip_hdr->ip_ttl, header->ver, pim_msg_len,
|
ifp->name, header->ver, pim_msg_len, checksum);
|
||||||
checksum);
|
if (PIM_DEBUG_PIM_PACKETDUMP_RECV)
|
||||||
if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
|
|
||||||
pim_pkt_dump(__func__, pim_msg, pim_msg_len);
|
pim_pkt_dump(__func__, pim_msg, pim_msg_len);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pim_pkt_dst_addr_ok(header->type, ip_hdr->ip_dst.s_addr)) {
|
if (!pim_pkt_dst_addr_ok(header->type, sg.grp)) {
|
||||||
char dst_str[INET_ADDRSTRLEN];
|
|
||||||
char src_str[INET_ADDRSTRLEN];
|
|
||||||
|
|
||||||
pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str,
|
|
||||||
sizeof(dst_str));
|
|
||||||
pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str,
|
|
||||||
sizeof(src_str));
|
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: Ignoring Pkt. Unexpected IP destination %s for %s (Expected: all_pim_routers_addr) from %s",
|
"%s: Ignoring Pkt. Unexpected IP destination %pPA for %s (Expected: all_pim_routers_addr) from %pPA",
|
||||||
__func__, dst_str, pim_pim_msgtype2str(header->type),
|
__func__, &sg.grp, pim_pim_msgtype2str(header->type),
|
||||||
src_str);
|
&sg.src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (header->type) {
|
switch (header->type) {
|
||||||
case PIM_MSG_TYPE_HELLO:
|
case PIM_MSG_TYPE_HELLO:
|
||||||
return pim_hello_recv(ifp, ip_hdr->ip_src,
|
return pim_hello_recv(ifp, sg.src, pim_msg + PIM_MSG_HEADER_LEN,
|
||||||
pim_msg + PIM_MSG_HEADER_LEN,
|
|
||||||
pim_msg_len - PIM_MSG_HEADER_LEN);
|
pim_msg_len - PIM_MSG_HEADER_LEN);
|
||||||
break;
|
break;
|
||||||
case PIM_MSG_TYPE_REGISTER:
|
case PIM_MSG_TYPE_REGISTER:
|
||||||
return pim_register_recv(ifp, ip_hdr->ip_dst, ip_hdr->ip_src,
|
return pim_register_recv(ifp, sg.grp, sg.src,
|
||||||
pim_msg + PIM_MSG_HEADER_LEN,
|
pim_msg + PIM_MSG_HEADER_LEN,
|
||||||
pim_msg_len - PIM_MSG_HEADER_LEN);
|
pim_msg_len - PIM_MSG_HEADER_LEN);
|
||||||
break;
|
break;
|
||||||
@ -280,38 +273,37 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
|
|||||||
pim_msg_len - PIM_MSG_HEADER_LEN);
|
pim_msg_len - PIM_MSG_HEADER_LEN);
|
||||||
break;
|
break;
|
||||||
case PIM_MSG_TYPE_JOIN_PRUNE:
|
case PIM_MSG_TYPE_JOIN_PRUNE:
|
||||||
neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
|
neigh = pim_neighbor_find(ifp, sg.src);
|
||||||
if (!neigh) {
|
if (!neigh) {
|
||||||
if (PIM_DEBUG_PIM_PACKETS)
|
if (PIM_DEBUG_PIM_PACKETS)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
|
"%s %s: non-hello PIM message type=%d from non-neighbor %pPA on %s",
|
||||||
__FILE__, __func__, header->type,
|
__FILE__, __func__, header->type,
|
||||||
src_str, ifp->name);
|
&sg.src, ifp->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pim_neighbor_timer_reset(neigh, neigh->holdtime);
|
pim_neighbor_timer_reset(neigh, neigh->holdtime);
|
||||||
return pim_joinprune_recv(ifp, neigh, ip_hdr->ip_src,
|
return pim_joinprune_recv(ifp, neigh, sg.src,
|
||||||
pim_msg + PIM_MSG_HEADER_LEN,
|
pim_msg + PIM_MSG_HEADER_LEN,
|
||||||
pim_msg_len - PIM_MSG_HEADER_LEN);
|
pim_msg_len - PIM_MSG_HEADER_LEN);
|
||||||
break;
|
break;
|
||||||
case PIM_MSG_TYPE_ASSERT:
|
case PIM_MSG_TYPE_ASSERT:
|
||||||
neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
|
neigh = pim_neighbor_find(ifp, sg.src);
|
||||||
if (!neigh) {
|
if (!neigh) {
|
||||||
if (PIM_DEBUG_PIM_PACKETS)
|
if (PIM_DEBUG_PIM_PACKETS)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
|
"%s %s: non-hello PIM message type=%d from non-neighbor %pPA on %s",
|
||||||
__FILE__, __func__, header->type,
|
__FILE__, __func__, header->type,
|
||||||
src_str, ifp->name);
|
&sg.src, ifp->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pim_neighbor_timer_reset(neigh, neigh->holdtime);
|
pim_neighbor_timer_reset(neigh, neigh->holdtime);
|
||||||
return pim_assert_recv(ifp, neigh, ip_hdr->ip_src,
|
return pim_assert_recv(ifp, neigh, sg.src,
|
||||||
pim_msg + PIM_MSG_HEADER_LEN,
|
pim_msg + PIM_MSG_HEADER_LEN,
|
||||||
pim_msg_len - PIM_MSG_HEADER_LEN);
|
pim_msg_len - PIM_MSG_HEADER_LEN);
|
||||||
break;
|
break;
|
||||||
case PIM_MSG_TYPE_BOOTSTRAP:
|
case PIM_MSG_TYPE_BOOTSTRAP:
|
||||||
return pim_bsm_process(ifp, ip_hdr, pim_msg, pim_msg_len,
|
return pim_bsm_process(ifp, &sg, pim_msg, pim_msg_len, no_fwd);
|
||||||
no_fwd);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -348,6 +340,8 @@ static void pim_sock_read(struct thread *t)
|
|||||||
pim_ifp = ifp->info;
|
pim_ifp = ifp->info;
|
||||||
|
|
||||||
while (cont) {
|
while (cont) {
|
||||||
|
pim_sgaddr sg;
|
||||||
|
|
||||||
len = pim_socket_recvfromto(fd, buf, sizeof(buf), &from,
|
len = pim_socket_recvfromto(fd, buf, sizeof(buf), &from,
|
||||||
&fromlen, &to, &tolen, &ifindex);
|
&fromlen, &to, &tolen, &ifindex);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
@ -377,7 +371,15 @@ static void pim_sock_read(struct thread *t)
|
|||||||
ifindex);
|
ifindex);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
int fail = pim_pim_packet(ifp, buf, len);
|
#if PIM_IPV == 4
|
||||||
|
sg.src = ((struct sockaddr_in *)&from)->sin_addr;
|
||||||
|
sg.grp = ((struct sockaddr_in *)&to)->sin_addr;
|
||||||
|
#else
|
||||||
|
sg.src = ((struct sockaddr_in6 *)&from)->sin6_addr;
|
||||||
|
sg.grp = ((struct sockaddr_in6 *)&to)->sin6_addr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int fail = pim_pim_packet(ifp, buf, len, sg);
|
||||||
if (fail) {
|
if (fail) {
|
||||||
if (PIM_DEBUG_PIM_PACKETS)
|
if (PIM_DEBUG_PIM_PACKETS)
|
||||||
zlog_debug("%s: pim_pim_packet() return=%d",
|
zlog_debug("%s: pim_pim_packet() return=%d",
|
||||||
|
@ -54,7 +54,8 @@ void pim_sock_delete(struct interface *ifp, const char *delete_message);
|
|||||||
void pim_hello_restart_now(struct interface *ifp);
|
void pim_hello_restart_now(struct interface *ifp);
|
||||||
void pim_hello_restart_triggered(struct interface *ifp);
|
void pim_hello_restart_triggered(struct interface *ifp);
|
||||||
|
|
||||||
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len);
|
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len,
|
||||||
|
pim_sgaddr sg);
|
||||||
|
|
||||||
int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
|
int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
|
||||||
int pim_msg_size, const char *ifname);
|
int pim_msg_size, const char *ifname);
|
||||||
|
Loading…
Reference in New Issue
Block a user