From: Donald Sharp Date: Thu, 28 Jul 2016 02:19:08 +0000 (-0400) Subject: pimd: Infrastructure to forward packet down (*,G) tree X-Git-Tag: frr-3.0-branchpoint~64^2~10^2~337 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=31c680fc88838cd7e0be8bf12165084d4cb03b52;p=mirror%2Ffrr.git pimd: Infrastructure to forward packet down (*,G) tree When a register is received, forward the packet as appropriate. This is the infrastructure to make this happen. Signed-off-by: Donald Sharp --- diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 79bfa4afc9..da84e245d4 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -348,6 +348,7 @@ pim_register_recv (struct interface *ifp, if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) && !(*bits & PIM_REGISTER_NR_BIT)) { + pim_rp_forward_packet (ip_hdr); //decapsulate and forward the iner packet to //inherited_olist(S,G,rpt) } diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index e7c03792cd..929211cdd8 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -39,10 +39,29 @@ static int i_am_rp = 0; */ static int fd_rp = -1; +void +pim_rp_forward_packet (struct ip *ip_hdr) +{ + struct sockaddr_in sin; + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = ip_hdr->ip_dst.s_addr; + + zlog_debug ("Sending Packet"); + if (sendto (fd_rp, ip_hdr, ntohs (ip_hdr->ip_len), 0, (struct sockaddr *)&sin, sizeof (struct sockaddr)) < 0) + { + zlog_debug ("Failure to send packet: %s", safe_strerror (errno)); + } +} + static void pim_rp_create_socket (void) { fd_rp = pim_socket_raw (IPPROTO_RAW); + + if (pim_socket_ip_hdr (fd_rp) != 0) + zlog_debug ("Unable to setup socket for ip hdr inclusion"); + if (pim_socket_bind (fd_rp, qpim_rp.source_nexthop.interface) != 0) zlog_debug ("Unable to Bind to a particular socket"); } diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index 35a7e9dfc7..ccbc5b6ad4 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -26,6 +26,7 @@ void pim_rp_check_rp (struct in_addr old, struct in_addr new); int pim_rp_i_am_rp (struct in_addr group); int pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source); struct pim_rpf *pim_rp_g (struct in_addr group); +void pim_rp_forward_packet (struct ip *ip_hdr); #define I_am_RP(G) pim_rp_i_am_rp ((G)) #define RP(G) pim_rp_g ((G)) diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index 70b18b14a4..a4155549c9 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -45,7 +45,8 @@ /* GLOBAL VARS */ extern struct zebra_privs_t pimd_privs; -int pim_socket_raw(int protocol) +int +pim_socket_raw (int protocol) { int fd; @@ -68,11 +69,31 @@ int pim_socket_raw(int protocol) return fd; } +int +pim_socket_ip_hdr (int fd) +{ + const int on = 1; + int ret; + + if (pimd_privs.change (ZPRIVS_RAISE)) + zlog_err ("%s: could not raise privs, %s", + __PRETTY_FUNCTION__, safe_strerror (errno)); + + ret = setsockopt (fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)); + + if (pimd_privs.change (ZPRIVS_LOWER)) + zlog_err ("%s: could not lower privs, %s", + __PRETTY_FUNCTION__, safe_strerror (errno)); + + return ret; +} + /* * Given a socket and a interface, * Bind that socket to that interface */ -int pim_socket_bind (int fd, struct interface *ifp) +int +pim_socket_bind (int fd, struct interface *ifp) { int ret; diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h index 51ad88e24e..c47d08f440 100644 --- a/pimd/pim_sock.h +++ b/pimd/pim_sock.h @@ -38,6 +38,7 @@ #define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */ int pim_socket_bind (int fd, struct interface *ifp); +int pim_socket_ip_hdr (int fd); int pim_socket_raw(int protocol); int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop); int pim_socket_join(int fd, struct in_addr group,