]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_msdp_packet.c
zebra: Allow ns delete to happen after under/over flow checks
[mirror_frr.git] / pimd / pim_msdp_packet.c
index 9a69bbd9cd697e17f660b01fa1a94ab84651830c..39e39b9557fe8596fce50952c643e016c3ad1fe2 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <zebra.h>
 
 #include <lib/stream.h>
 #include <lib/thread.h>
 #include <lib/vty.h>
+#include <lib/lib_errors.h>
 
 #include "pimd.h"
 #include "pim_str.h"
+#include "pim_errors.h"
 
 #include "pim_msdp.h"
 #include "pim_msdp_packet.h"
@@ -146,7 +147,8 @@ static void pim_msdp_connect_check(struct pim_msdp_peer *mp)
 
        /* If getsockopt is fail, this is fatal error. */
        if (ret < 0) {
-               zlog_err("can't get sockopt for nonblocking connect");
+               flog_err_sys(EC_LIB_SOCKET,
+                            "can't get sockopt for nonblocking connect");
                pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
                return;
        }
@@ -222,7 +224,7 @@ int pim_msdp_write(struct thread *thread)
                writenum = stream_get_endp(s) - stream_get_getp(s);
 
                /* Call write() system call */
-               num = write(mp->fd, STREAM_PNT(s), writenum);
+               num = write(mp->fd, stream_pnt(s), writenum);
                if (num < 0) {
                        /* write failed either retry needed or error */
                        if (ERRNO_IO_RETRY(errno)) {
@@ -311,7 +313,8 @@ void pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp)
        pim_msdp_pkt_send(mp, s);
 }
 
-static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_instance *pim,
+                                            struct pim_msdp_peer *mp)
 {
        struct stream *s;
 
@@ -319,7 +322,7 @@ static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_msdp_peer *mp)
                /* don't tx anything unless a session is established */
                return;
        }
-       s = stream_dup(msdp->work_obuf);
+       s = stream_dup(pim->msdp.work_obuf);
        if (s) {
                pim_msdp_pkt_send(mp, s);
                mp->flags |= PIM_MSDP_PEERF_SA_JUST_SENT;
@@ -327,63 +330,66 @@ static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_msdp_peer *mp)
 }
 
 /* push the stream into the obuf fifo of all the peers */
-static void pim_msdp_pkt_sa_push(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_sa_push(struct pim_instance *pim,
+                                struct pim_msdp_peer *mp)
 {
        struct listnode *mpnode;
 
        if (mp) {
-               pim_msdp_pkt_sa_push_to_one_peer(mp);
+               pim_msdp_pkt_sa_push_to_one_peer(pim, mp);
        } else {
-               for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+               for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
                        if (PIM_DEBUG_MSDP_INTERNAL) {
                                zlog_debug("MSDP peer %s pim_msdp_pkt_sa_push",
                                           mp->key_str);
                        }
-                       pim_msdp_pkt_sa_push_to_one_peer(mp);
+                       pim_msdp_pkt_sa_push_to_one_peer(pim, mp);
                }
        }
 }
 
-static int pim_msdp_pkt_sa_fill_hdr(int local_cnt)
+static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt)
 {
        int curr_tlv_ecnt;
 
-       stream_reset(msdp->work_obuf);
+       stream_reset(pim->msdp.work_obuf);
        curr_tlv_ecnt = local_cnt > PIM_MSDP_SA_MAX_ENTRY_CNT
                                ? PIM_MSDP_SA_MAX_ENTRY_CNT
                                : local_cnt;
        local_cnt -= curr_tlv_ecnt;
-       stream_putc(msdp->work_obuf, PIM_MSDP_V4_SOURCE_ACTIVE);
-       stream_putw(msdp->work_obuf, PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt));
-       stream_putc(msdp->work_obuf, curr_tlv_ecnt);
-       stream_put_ipv4(msdp->work_obuf, msdp->originator_id.s_addr);
+       stream_putc(pim->msdp.work_obuf, PIM_MSDP_V4_SOURCE_ACTIVE);
+       stream_putw(pim->msdp.work_obuf,
+                   PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt));
+       stream_putc(pim->msdp.work_obuf, curr_tlv_ecnt);
+       stream_put_ipv4(pim->msdp.work_obuf, pim->msdp.originator_id.s_addr);
 
        return local_cnt;
 }
 
 static void pim_msdp_pkt_sa_fill_one(struct pim_msdp_sa *sa)
 {
-       stream_put3(msdp->work_obuf, 0 /* reserved */);
-       stream_putc(msdp->work_obuf, 32 /* sprefix len */);
-       stream_put_ipv4(msdp->work_obuf, sa->sg.grp.s_addr);
-       stream_put_ipv4(msdp->work_obuf, sa->sg.src.s_addr);
+       stream_put3(sa->pim->msdp.work_obuf, 0 /* reserved */);
+       stream_putc(sa->pim->msdp.work_obuf, 32 /* sprefix len */);
+       stream_put_ipv4(sa->pim->msdp.work_obuf, sa->sg.grp.s_addr);
+       stream_put_ipv4(sa->pim->msdp.work_obuf, sa->sg.src.s_addr);
 }
 
-static void pim_msdp_pkt_sa_gen(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
+                               struct pim_msdp_peer *mp)
 {
        struct listnode *sanode;
        struct pim_msdp_sa *sa;
        int sa_count;
-       int local_cnt = msdp->local_cnt;
+       int local_cnt = pim->msdp.local_cnt;
 
        sa_count = 0;
        if (PIM_DEBUG_MSDP_INTERNAL) {
                zlog_debug("  sa gen  %d", local_cnt);
        }
 
-       local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
+       local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt);
 
-       for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+       for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
                if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
                        /* current implementation of MSDP is for anycast i.e.
                         * full mesh. so
@@ -395,31 +401,31 @@ static void pim_msdp_pkt_sa_gen(struct pim_msdp_peer *mp)
                pim_msdp_pkt_sa_fill_one(sa);
                ++sa_count;
                if (sa_count >= PIM_MSDP_SA_MAX_ENTRY_CNT) {
-                       pim_msdp_pkt_sa_push(mp);
+                       pim_msdp_pkt_sa_push(pim, mp);
                        /* reset headers */
                        sa_count = 0;
                        if (PIM_DEBUG_MSDP_INTERNAL) {
                                zlog_debug("  sa gen for remainder %d",
                                           local_cnt);
                        }
-                       local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
+                       local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt);
                }
        }
 
        if (sa_count) {
-               pim_msdp_pkt_sa_push(mp);
+               pim_msdp_pkt_sa_push(pim, mp);
        }
        return;
 }
 
-static void pim_msdp_pkt_sa_tx_done(void)
+static void pim_msdp_pkt_sa_tx_done(struct pim_instance *pim)
 {
        struct listnode *mpnode;
        struct pim_msdp_peer *mp;
 
        /* if SA were sent to the peers we restart ka timer and avoid
         * unnecessary ka noise */
-       for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+       for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
                if (mp->flags & PIM_MSDP_PEERF_SA_JUST_SENT) {
                        mp->flags &= ~PIM_MSDP_PEERF_SA_JUST_SENT;
                        pim_msdp_peer_pkt_txed(mp);
@@ -427,25 +433,25 @@ static void pim_msdp_pkt_sa_tx_done(void)
        }
 }
 
-void pim_msdp_pkt_sa_tx(void)
+void pim_msdp_pkt_sa_tx(struct pim_instance *pim)
 {
-       pim_msdp_pkt_sa_gen(NULL /* mp */);
-       pim_msdp_pkt_sa_tx_done();
+       pim_msdp_pkt_sa_gen(pim, NULL /* mp */);
+       pim_msdp_pkt_sa_tx_done(pim);
 }
 
 void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa)
 {
-       pim_msdp_pkt_sa_fill_hdr(1 /* cnt */);
+       pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */);
        pim_msdp_pkt_sa_fill_one(sa);
-       pim_msdp_pkt_sa_push(NULL);
-       pim_msdp_pkt_sa_tx_done();
+       pim_msdp_pkt_sa_push(sa->pim, NULL);
+       pim_msdp_pkt_sa_tx_done(sa->pim);
 }
 
 /* when a connection is first established we push all SAs immediately */
 void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp)
 {
-       pim_msdp_pkt_sa_gen(mp);
-       pim_msdp_pkt_sa_tx_done();
+       pim_msdp_pkt_sa_gen(mp->pim, mp);
+       pim_msdp_pkt_sa_tx_done(mp->pim);
 }
 
 static void pim_msdp_pkt_rxed_with_fatal_error(struct pim_msdp_peer *mp)
@@ -478,14 +484,15 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
 
        if (prefix_len != 32) {
                /* ignore SA update if the prefix length is not 32 */
-               zlog_err("rxed sa update with invalid prefix length %d",
+               flog_err(EC_PIM_MSDP_PACKET,
+                        "rxed sa update with invalid prefix length %d",
                         prefix_len);
                return;
        }
        if (PIM_DEBUG_MSDP_PACKETS) {
                zlog_debug("  sg %s", pim_str_sg_dump(&sg));
        }
-       pim_msdp_sa_ref(mp, &sg, rp);
+       pim_msdp_sa_ref(mp->pim, mp, &sg, rp);
 }
 
 static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)