mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 10:09:25 +00:00
Merge pull request #10742 from plsaranya/pim_register
pim6d: Register message send handling
This commit is contained in:
commit
de416e6782
@ -37,21 +37,6 @@ void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr addr)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* PIM register
|
||||
*/
|
||||
void pim_register_join(struct pim_upstream *up)
|
||||
{
|
||||
}
|
||||
|
||||
void pim_null_register_send(struct pim_upstream *up)
|
||||
{
|
||||
}
|
||||
|
||||
void pim_reg_del_on_couldreg_fail(struct interface *ifp)
|
||||
{
|
||||
}
|
||||
|
||||
bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
|
||||
{
|
||||
return false;
|
||||
@ -80,25 +65,3 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pim_register_send(const uint8_t *buf, int buf_size, pim_addr src,
|
||||
struct pim_rpf *rpg, int null_register,
|
||||
struct pim_upstream *up)
|
||||
{
|
||||
}
|
||||
|
||||
void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg, pim_addr src,
|
||||
pim_addr originator)
|
||||
{
|
||||
}
|
||||
|
||||
int pim_register_recv(struct interface *ifp, pim_addr dest_addr,
|
||||
pim_addr src_addr, uint8_t *tlv_buf, int tlv_buf_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "pim_util.h"
|
||||
#include "pim_ssm.h"
|
||||
#include "pim_vxlan.h"
|
||||
#include "pim_addr.h"
|
||||
|
||||
struct thread *send_test_packet_timer = NULL;
|
||||
|
||||
@ -64,8 +65,8 @@ void pim_register_join(struct pim_upstream *up)
|
||||
pim_vxlan_update_sg_reg_state(pim, up, true);
|
||||
}
|
||||
|
||||
void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,
|
||||
struct in_addr src, struct in_addr originator)
|
||||
void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg, pim_addr src,
|
||||
pim_addr originator)
|
||||
{
|
||||
struct pim_interface *pinfo;
|
||||
unsigned char buffer[10000];
|
||||
@ -74,7 +75,7 @@ void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,
|
||||
uint8_t *b1;
|
||||
|
||||
if (PIM_DEBUG_PIM_REG) {
|
||||
zlog_debug("Sending Register stop for %pSG to %pI4 on %s", sg,
|
||||
zlog_debug("Sending Register stop for %pSG to %pPA on %s", sg,
|
||||
&originator, ifp->name);
|
||||
}
|
||||
|
||||
@ -218,7 +219,7 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
|
||||
void pim_register_send(const uint8_t *buf, int buf_size, pim_addr src,
|
||||
struct pim_rpf *rpg, int null_register,
|
||||
struct pim_upstream *up)
|
||||
{
|
||||
@ -226,11 +227,11 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
|
||||
unsigned char *b1;
|
||||
struct pim_interface *pinfo;
|
||||
struct interface *ifp;
|
||||
pim_addr dst = pim_addr_from_prefix(&rpg->rpf_addr);
|
||||
|
||||
if (PIM_DEBUG_PIM_REG) {
|
||||
zlog_debug("Sending %s %sRegister Packet to %pI4", up->sg_str,
|
||||
null_register ? "NULL " : "",
|
||||
&rpg->rpf_addr.u.prefix4);
|
||||
zlog_debug("Sending %s %sRegister Packet to %pPA", up->sg_str,
|
||||
null_register ? "NULL " : "", &dst);
|
||||
}
|
||||
|
||||
ifp = rpg->source_nexthop.interface;
|
||||
@ -250,9 +251,9 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
|
||||
}
|
||||
|
||||
if (PIM_DEBUG_PIM_REG) {
|
||||
zlog_debug("%s: Sending %s %sRegister Packet to %pI4 on %s",
|
||||
zlog_debug("%s: Sending %s %sRegister Packet to %pPA on %s",
|
||||
__func__, up->sg_str, null_register ? "NULL " : "",
|
||||
&rpg->rpf_addr.u.prefix4, ifp->name);
|
||||
&dst, ifp->name);
|
||||
}
|
||||
|
||||
memset(buffer, 0, 10000);
|
||||
@ -262,14 +263,13 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
|
||||
|
||||
memcpy(b1, (const unsigned char *)buf, buf_size);
|
||||
|
||||
pim_msg_build_header(src, rpg->rpf_addr.u.prefix4, buffer,
|
||||
buf_size + PIM_MSG_REGISTER_LEN,
|
||||
pim_msg_build_header(src, dst, buffer, buf_size + PIM_MSG_REGISTER_LEN,
|
||||
PIM_MSG_TYPE_REGISTER, false);
|
||||
|
||||
++pinfo->pim_ifstat_reg_send;
|
||||
|
||||
if (pim_msg_send(pinfo->pim_sock_fd, src, rpg->rpf_addr.u.prefix4,
|
||||
buffer, buf_size + PIM_MSG_REGISTER_LEN, ifp->name)) {
|
||||
if (pim_msg_send(pinfo->pim_sock_fd, src, dst, buffer,
|
||||
buf_size + PIM_MSG_REGISTER_LEN, ifp->name)) {
|
||||
if (PIM_DEBUG_PIM_TRACE) {
|
||||
zlog_debug(
|
||||
"%s: could not send PIM register message on interface %s",
|
||||
@ -279,12 +279,13 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
|
||||
}
|
||||
}
|
||||
|
||||
#if PIM_IPV == 4
|
||||
void pim_null_register_send(struct pim_upstream *up)
|
||||
{
|
||||
struct ip ip_hdr;
|
||||
struct pim_interface *pim_ifp;
|
||||
struct pim_rpf *rpg;
|
||||
struct in_addr src;
|
||||
pim_addr src;
|
||||
|
||||
pim_ifp = up->rpf.source_nexthop.interface->info;
|
||||
if (!pim_ifp) {
|
||||
@ -323,9 +324,71 @@ void pim_null_register_send(struct pim_upstream *up)
|
||||
return;
|
||||
}
|
||||
}
|
||||
pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip),
|
||||
src, rpg, 1, up);
|
||||
pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip), src, rpg, 1,
|
||||
up);
|
||||
}
|
||||
#else
|
||||
void pim_null_register_send(struct pim_upstream *up)
|
||||
{
|
||||
struct ip6_hdr ip6_hdr;
|
||||
struct pim_msg_header pim_msg_header;
|
||||
struct pim_interface *pim_ifp;
|
||||
struct pim_rpf *rpg;
|
||||
pim_addr src;
|
||||
unsigned char buffer[sizeof(ip6_hdr) + sizeof(pim_msg_header)];
|
||||
struct ipv6_ph ph;
|
||||
|
||||
pim_ifp = up->rpf.source_nexthop.interface->info;
|
||||
if (!pim_ifp) {
|
||||
if (PIM_DEBUG_PIM_TRACE)
|
||||
zlog_debug(
|
||||
"Cannot send null-register for %s no valid iif",
|
||||
up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
rpg = RP(pim_ifp->pim, up->sg.grp);
|
||||
if (!rpg) {
|
||||
if (PIM_DEBUG_PIM_TRACE)
|
||||
zlog_debug(
|
||||
"Cannot send null-register for %s no RPF to the RP",
|
||||
up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ip6_hdr, 0, sizeof(ip6_hdr));
|
||||
ip6_hdr.ip6_nxt = PIM_IP_PROTO_PIM;
|
||||
ip6_hdr.ip6_plen = PIM_MSG_HEADER_LEN;
|
||||
ip6_hdr.ip6_vfc = 6 << 4;
|
||||
ip6_hdr.ip6_hlim = MAXTTL;
|
||||
ip6_hdr.ip6_src = up->sg.src;
|
||||
ip6_hdr.ip6_dst = up->sg.grp;
|
||||
|
||||
memset(buffer, 0, (sizeof(ip6_hdr) + sizeof(pim_msg_header)));
|
||||
memcpy(buffer, &ip6_hdr, sizeof(ip6_hdr));
|
||||
|
||||
pim_msg_header.ver = 0;
|
||||
pim_msg_header.type = 0;
|
||||
pim_msg_header.reserved = 0;
|
||||
|
||||
pim_msg_header.checksum = 0;
|
||||
|
||||
ph.src = up->sg.src;
|
||||
ph.dst = up->sg.grp;
|
||||
ph.ulpl = htonl(PIM_MSG_HEADER_LEN);
|
||||
ph.next_hdr = IPPROTO_PIM;
|
||||
pim_msg_header.checksum =
|
||||
in_cksum_with_ph6(&ph, &pim_msg_header, PIM_MSG_HEADER_LEN);
|
||||
|
||||
memcpy(buffer + sizeof(ip6_hdr), &pim_msg_header, PIM_MSG_HEADER_LEN);
|
||||
|
||||
|
||||
src = pim_ifp->primary_address;
|
||||
pim_register_send((uint8_t *)buffer,
|
||||
sizeof(ip6_hdr) + PIM_MSG_HEADER_LEN, src, rpg, 1,
|
||||
up);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.4.2 Receiving Register Messages at the RP
|
||||
@ -425,6 +488,46 @@ int pim_register_recv(struct interface *ifp, pim_addr dest_addr,
|
||||
memset(&sg, 0, sizeof(sg));
|
||||
sg = pim_sgaddr_from_iphdr(ip_hdr);
|
||||
|
||||
#if PIM_IPV == 6
|
||||
/*
|
||||
* According to RFC section 4.9.3, If Dummy PIM Header is included
|
||||
* in NULL Register as a payload there would be two PIM headers.
|
||||
* The inner PIM Header's checksum field should also be validated
|
||||
* in addition to the outer PIM Header's checksum. Validation of
|
||||
* inner PIM header checksum is done here.
|
||||
*/
|
||||
if ((*bits & PIM_REGISTER_NR_BIT) &&
|
||||
((tlv_buf_size - PIM_MSG_REGISTER_BIT_RESERVED_LEN) >
|
||||
(int)sizeof(struct ip6_hdr))) {
|
||||
uint16_t computed_checksum;
|
||||
uint16_t received_checksum;
|
||||
struct ipv6_ph ph;
|
||||
struct pim_msg_header *header;
|
||||
|
||||
header = (struct pim_msg_header
|
||||
*)(tlv_buf +
|
||||
PIM_MSG_REGISTER_BIT_RESERVED_LEN +
|
||||
sizeof(struct ip6_hdr));
|
||||
ph.src = sg.src;
|
||||
ph.dst = sg.grp;
|
||||
ph.ulpl = htonl(PIM_MSG_HEADER_LEN);
|
||||
ph.next_hdr = IPPROTO_PIM;
|
||||
|
||||
received_checksum = header->checksum;
|
||||
|
||||
header->checksum = 0;
|
||||
computed_checksum = in_cksum_with_ph6(
|
||||
&ph, header, htonl(PIM_MSG_HEADER_LEN));
|
||||
|
||||
if (computed_checksum != received_checksum) {
|
||||
if (PIM_DEBUG_PIM_PACKETS)
|
||||
zlog_debug(
|
||||
"Ignoring Null Register message%pSG from %pPA due to bad checksum in Encapsulated dummy PIM header",
|
||||
&sg, &src_addr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
i_am_rp = I_am_RP(pim, sg.grp);
|
||||
|
||||
if (PIM_DEBUG_PIM_REG)
|
||||
|
@ -57,6 +57,7 @@ pim_common = \
|
||||
pimd/pim_zebra.c \
|
||||
pimd/pim_zlookup.c \
|
||||
pimd/pim_vxlan.c \
|
||||
pimd/pim_register.c \
|
||||
pimd/pimd.c \
|
||||
# end
|
||||
|
||||
@ -74,7 +75,6 @@ pimd_pimd_SOURCES = \
|
||||
pimd/pim_msdp.c \
|
||||
pimd/pim_msdp_packet.c \
|
||||
pimd/pim_msdp_socket.c \
|
||||
pimd/pim_register.c \
|
||||
pimd/pim_signals.c \
|
||||
pimd/pim_zpthread.c \
|
||||
pimd/pim_mroute_msg.c \
|
||||
|
Loading…
Reference in New Issue
Block a user