back to topotato report
topotato coverage report
Current view: top level - pimd - pim_oil.h (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 23 25 92.0 %
Date: 2023-02-24 14:41:08 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * PIM for Quagga
       3             :  * Copyright (C) 2008  Everton da Silva Marques
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or modify
       6             :  * it under the terms of the GNU General Public License as published by
       7             :  * the Free Software Foundation; either version 2 of the License, or
       8             :  * (at your option) any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful, but
      11             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License along
      16             :  * with this program; see the file COPYING; if not, write to the Free Software
      17             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      18             :  */
      19             : 
      20             : #ifndef PIM_OIL_H
      21             : #define PIM_OIL_H
      22             : 
      23             : struct pim_interface;
      24             : 
      25             : #include "pim_mroute.h"
      26             : 
      27             : /*
      28             :  * Where did we get this (S,G) from?
      29             :  *
      30             :  * GM - Learned from IGMP/MLD
      31             :  * PIM - Learned from PIM
      32             :  * SOURCE - Learned from Source multicast packet received
      33             :  * STAR - Inherited
      34             :  */
      35             : #define PIM_OIF_FLAG_PROTO_GM     (1 << 0)
      36             : #define PIM_OIF_FLAG_PROTO_PIM    (1 << 1)
      37             : #define PIM_OIF_FLAG_PROTO_STAR   (1 << 2)
      38             : #define PIM_OIF_FLAG_PROTO_VXLAN  (1 << 3)
      39             : #define PIM_OIF_FLAG_PROTO_ANY                                                 \
      40             :         (PIM_OIF_FLAG_PROTO_GM | PIM_OIF_FLAG_PROTO_PIM |                      \
      41             :          PIM_OIF_FLAG_PROTO_STAR | PIM_OIF_FLAG_PROTO_VXLAN)
      42             : 
      43             : /* OIF is present in the OIL but must not be used for forwarding traffic */
      44             : #define PIM_OIF_FLAG_MUTE         (1 << 4)
      45             : /*
      46             :  * We need a pimreg vif id from the kernel.
      47             :  * Since ifindex == vif id for most cases and the number
      48             :  * of expected interfaces is at most 100, using MAXVIFS -1
      49             :  * is probably ok.
      50             :  * Don't come running to me if this assumption is bad,
      51             :  * fix it.
      52             :  */
      53             : #define PIM_OIF_PIM_REGISTER_VIF   0
      54             : #define PIM_MAX_USABLE_VIFS        (MAXVIFS - 1)
      55             : 
      56             : struct channel_counts {
      57             :         unsigned long long lastused;
      58             :         unsigned long origpktcnt;
      59             :         unsigned long pktcnt;
      60             :         unsigned long oldpktcnt;
      61             :         unsigned long origbytecnt;
      62             :         unsigned long bytecnt;
      63             :         unsigned long oldbytecnt;
      64             :         unsigned long origwrong_if;
      65             :         unsigned long wrong_if;
      66             :         unsigned long oldwrong_if;
      67             : };
      68             : 
      69             : /*
      70             :   qpim_channel_oil_list holds a list of struct channel_oil.
      71             : 
      72             :   Each channel_oil.oil is used to control an (S,G) entry in the Kernel
      73             :   Multicast Forwarding Cache.
      74             : 
      75             :   There is a case when we create a channel_oil but don't install in the kernel
      76             : 
      77             :   Case where (S, G) entry not installed in the kernel:
      78             :     FRR receives IGMP/PIM (*, G) join and RP is not configured or
      79             :     not-reachable, then create a channel_oil for the group G with the incoming
      80             :     interface(channel_oil.oil.mfcc_parent) as invalid i.e "MAXVIF" and populate
      81             :     the outgoing interface where join is received. Keep this entry in the stack,
      82             :     but don't install in the kernel(channel_oil.installed = 0).
      83             : 
      84             :   Case where (S, G) entry installed in the kernel:
      85             :     When RP is configured and is reachable for the group G, and receiving a
      86             :     join if channel_oil is already present then populate the incoming interface
      87             :     and install the entry in the kernel, if channel_oil not present, then create
      88             :     a new_channel oil(channel_oil.installed = 1).
      89             : 
      90             :   is_valid: indicate if this entry is valid to get installed in kernel.
      91             :   installed: indicate if this entry is installed in the kernel.
      92             : 
      93             : */
      94             : PREDECL_RBTREE_UNIQ(rb_pim_oil);
      95             : 
      96             : struct channel_oil {
      97             :         struct pim_instance *pim;
      98             : 
      99             :         struct rb_pim_oil_item oil_rb;
     100             : 
     101             : #if PIM_IPV == 4
     102             :         struct mfcctl oil;
     103             : #else
     104             :         struct mf6cctl oil;
     105             : #endif
     106             :         int installed;
     107             :         int oil_inherited_rescan;
     108             :         int oil_size;
     109             :         int oil_ref_count;
     110             :         time_t oif_creation[MAXVIFS];
     111             :         uint32_t oif_flags[MAXVIFS];
     112             :         struct channel_counts cc;
     113             :         struct pim_upstream *up;
     114             :         time_t mroute_creation;
     115             : };
     116             : 
     117             : #if PIM_IPV == 4
     118          24 : static inline pim_addr *oil_origin(struct channel_oil *c_oil)
     119             : {
     120          24 :         return &c_oil->oil.mfcc_origin;
     121             : }
     122             : 
     123           0 : static inline pim_addr *oil_mcastgrp(struct channel_oil *c_oil)
     124             : {
     125           0 :         return &c_oil->oil.mfcc_mcastgrp;
     126             : }
     127             : 
     128             : static inline vifi_t *oil_parent(struct channel_oil *c_oil)
     129             : {
     130             :         return &c_oil->oil.mfcc_parent;
     131             : }
     132             : 
     133         532 : static inline bool oil_if_has(struct channel_oil *c_oil, vifi_t ifi)
     134             : {
     135         532 :         return !!c_oil->oil.mfcc_ttls[ifi];
     136             : }
     137             : 
     138         554 : static inline void oil_if_set(struct channel_oil *c_oil, vifi_t ifi, uint8_t set)
     139             : {
     140          27 :         c_oil->oil.mfcc_ttls[ifi] = set;
     141         527 : }
     142             : 
     143          27 : static inline int oil_if_cmp(struct mfcctl *oil1, struct mfcctl *oil2)
     144             : {
     145          27 :         return memcmp(&oil1->mfcc_ttls[0], &oil2->mfcc_ttls[0],
     146             :                       sizeof(oil1->mfcc_ttls));
     147             : }
     148             : #else
     149          37 : static inline pim_addr *oil_origin(struct channel_oil *c_oil)
     150             : {
     151          37 :         return &c_oil->oil.mf6cc_origin.sin6_addr;
     152             : }
     153             : 
     154          17 : static inline pim_addr *oil_mcastgrp(struct channel_oil *c_oil)
     155             : {
     156          17 :         return &c_oil->oil.mf6cc_mcastgrp.sin6_addr;
     157             : }
     158             : 
     159             : static inline mifi_t *oil_parent(struct channel_oil *c_oil)
     160             : {
     161             :         return &c_oil->oil.mf6cc_parent;
     162             : }
     163             : 
     164        5928 : static inline bool oil_if_has(struct channel_oil *c_oil, mifi_t ifi)
     165             : {
     166        5928 :         return !!IF_ISSET(ifi, &c_oil->oil.mf6cc_ifset);
     167             : }
     168             : 
     169        2607 : static inline void oil_if_set(struct channel_oil *c_oil, mifi_t ifi,
     170             :                               uint8_t set)
     171             : {
     172        2574 :         if (set)
     173          16 :                 IF_SET(ifi, &c_oil->oil.mf6cc_ifset);
     174             :         else
     175        2558 :                 IF_CLR(ifi, &c_oil->oil.mf6cc_ifset);
     176        2593 : }
     177             : 
     178          33 : static inline int oil_if_cmp(struct mf6cctl *oil1, struct mf6cctl *oil2)
     179             : {
     180          33 :         return memcmp(&oil1->mf6cc_ifset, &oil2->mf6cc_ifset,
     181             :                       sizeof(oil1->mf6cc_ifset));
     182             : }
     183             : #endif
     184             : 
     185             : extern int pim_channel_oil_compare(const struct channel_oil *c1,
     186             :                                    const struct channel_oil *c2);
     187         251 : DECLARE_RBTREE_UNIQ(rb_pim_oil, struct channel_oil, oil_rb,
     188             :                     pim_channel_oil_compare);
     189             : 
     190             : void pim_oil_init(struct pim_instance *pim);
     191             : void pim_oil_terminate(struct pim_instance *pim);
     192             : 
     193             : void pim_channel_oil_free(struct channel_oil *c_oil);
     194             : struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
     195             :                                          pim_sgaddr *sg);
     196             : struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
     197             :                                         pim_sgaddr *sg, const char *name);
     198             : struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil,
     199             :                                         const char *name);
     200             : 
     201             : int pim_channel_add_oif(struct channel_oil *c_oil, struct interface *oif,
     202             :                         uint32_t proto_mask, const char *caller);
     203             : int pim_channel_del_oif(struct channel_oil *c_oil, struct interface *oif,
     204             :                         uint32_t proto_mask, const char *caller);
     205             : 
     206             : int pim_channel_oil_empty(struct channel_oil *c_oil);
     207             : 
     208             : char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size);
     209             : 
     210             : void pim_channel_update_oif_mute(struct channel_oil *c_oil,
     211             :                 struct pim_interface *pim_ifp);
     212             : 
     213             : void pim_channel_oil_upstream_deref(struct channel_oil *c_oil);
     214             : void pim_channel_del_inherited_oif(struct channel_oil *c_oil,
     215             :                                    struct interface *oif, const char *caller);
     216             : 
     217             : #endif /* PIM_OIL_H */

Generated by: LCOV version v1.16-topotato