diff options
Diffstat (limited to 'bgpd/bgp_common.c')
-rw-r--r-- | bgpd/bgp_common.c | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/bgpd/bgp_common.c b/bgpd/bgp_common.c new file mode 100644 index 00000000..15ecdf3b --- /dev/null +++ b/bgpd/bgp_common.c @@ -0,0 +1,230 @@ +/* BGP Common -- header + * Copyright (C) 2009 Chris Hall (GMCH), Highwayman + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "bgpd/bgp_common.h" +#include "lib/zassert.h" + +/*============================================================================== + * Conversion qafx_bit_t -> qafx_num_t. + * + * If no bits are set, returns qafx_num_undef. + * + * If more than one bit is set, returns the lowest number qafx. + * + * NB: this is not built for speed. + * + * NB: it is a mistake to convert a value > qafx_bits_max (FATAL unless NDEBUG) + */ +extern qafx_num_t +qafx_num(qafx_bit_t bit) +{ + qafx_num_t num ; + dassert(bit <= qafx_bits_max) ; + + if (bit == 0) + return qafx_num_undef ; + + num = 0 ; + + while ((bit & 0xF) == 0) + { + num += 4 ; + bit >>= 4 ; + } + + while ((bit & 1) == 0) + { + num += 1; + bit >>= 1 ; + } ; + + return num ; +} ; + +/*============================================================================== + * Conversion tables for qafx_num => qAFI and qSAFI + * and qafx_num => iAFI and iSAFI + */ + +const qAFI_t qAFI_map[] = + { + [qafx_ipv4_unicast] = qAFI_IPV4, + [qafx_ipv4_multicast] = qAFI_IPV4, + [qafx_ipv4_mpls_vpn] = qAFI_IPV4, + [qafx_ipv6_unicast] = qAFI_IPV6, + [qafx_ipv6_multicast] = qAFI_IPV6, + [qafx_ipv6_mpls_vpn] = qAFI_IPV6, + [qafx_num_other] = qAFI_undef + } ; + +const qSAFI_t qSAFI_map[] = + { + [qafx_ipv4_unicast] = qSAFI_Unicast, + [qafx_ipv4_multicast] = qSAFI_Multicast, + [qafx_ipv4_mpls_vpn] = qSAFI_MPLS_VPN, + [qafx_ipv6_unicast] = qSAFI_Unicast, + [qafx_ipv6_multicast] = qSAFI_Multicast, + [qafx_ipv6_mpls_vpn] = qSAFI_MPLS_VPN, + [qafx_num_other] = qSAFI_undef + } ; + +const iAFI_t iAFI_map[] = + { + [qafx_ipv4_unicast] = iAFI_IPV4, + [qafx_ipv4_multicast] = iAFI_IPV4, + [qafx_ipv4_mpls_vpn] = iAFI_IPV4, + [qafx_ipv6_unicast] = iAFI_IPV6, + [qafx_ipv6_multicast] = iAFI_IPV6, + [qafx_ipv6_mpls_vpn] = iAFI_IPV6, + [qafx_num_other] = iAFI_Reserved + } ; + +const iSAFI_t iSAFI_map[] = + { + [qafx_ipv4_unicast] = iSAFI_Unicast, + [qafx_ipv4_multicast] = iSAFI_Multicast, + [qafx_ipv4_mpls_vpn] = iSAFI_MPLS_VPN, + [qafx_ipv6_unicast] = iSAFI_Unicast, + [qafx_ipv6_multicast] = iSAFI_Multicast, + [qafx_ipv6_mpls_vpn] = iSAFI_MPLS_VPN, + [qafx_num_other] = iSAFI_Reserved, + } ; + +/*============================================================================== + * Convert iAFI/iSAFI => qafx_num_t + * and qAFI/qSAFI => qafx_num_t + */ + +/* iAFI/iSAFI = qafx_num_t unknowns => qafx_num_other + * reserved => qafx_num_undef + */ +extern qafx_num_t +qafx_num_from_iAFI_iSAFI(iAFI_t afi, iSAFI_t safi) +{ + switch (afi) + { + case iAFI_Reserved: + return qafx_num_undef ; /* no matter what the iSAFI is */ + + case iAFI_IP: + switch(safi) + { + case iSAFI_Reserved: + return qafx_num_undef ; /* no matter what the iAFI is */ + case iSAFI_Unicast: + return qafx_ipv4_unicast ; + case iSAFI_Multicast: + return qafx_ipv4_multicast ; + case iSAFI_MPLS_VPN: + return qafx_ipv4_mpls_vpn ; + default: + break ; + } ; + break ; + + case iAFI_IP6: + switch(safi) + { + case iSAFI_Reserved: + return qafx_num_undef ; /* no matter what the iAFI is */ + case iSAFI_Unicast: + return qafx_ipv6_unicast ; + case iSAFI_Multicast: + return qafx_ipv6_multicast ; + case iSAFI_MPLS_VPN: + return qafx_ipv6_mpls_vpn ; + default: + break ; + } ; + break ; + + default: + switch(safi) + { + case iSAFI_Reserved: + return qafx_num_undef ; /* no matter what the iAFI is */ + default: + break ; + } ; + break ; + } ; + + return qafx_num_other ; +} ; + +/* qAFI/qSAFI = qafx_num_t + * + * NB: qAFI_undef with any qSAFI_xxx => qafx_num_undef + * qSAFI_undef with any qAFI_xxx => qafx_num_undef + * qSAFI_Unused qith any qAFI_xxx => qafx_num_undef + * + * NB: any unrecognised qAFI/qSAFI combinations => FATAL error + */ +extern qafx_num_t +qafx_num_from_qAFI_qSAFI(qAFI_t afi, qSAFI_t safi) +{ + switch (afi) + { + case qAFI_undef: + if ((safi >= qSAFI_min) && (safi <= qSAFI_max)) + return qafx_num_undef ; /* for all valid qSAFI */ + break ; + + case qAFI_IP: + switch(safi) + { + case qSAFI_undef: + case qSAFI_Unused: + return qafx_num_undef ; + case qSAFI_Unicast: + return qafx_ipv4_unicast ; + case qSAFI_Multicast: + return qafx_ipv4_multicast ; + case qSAFI_MPLS_VPN: + return qafx_ipv4_mpls_vpn ; + default: + break ; + } ; + break ; + + case qAFI_IP6: + switch(safi) + { + case qSAFI_undef: + case qSAFI_Unused: + return qafx_num_undef ; + case qSAFI_Unicast: + return qafx_ipv6_unicast ; + case qSAFI_Multicast: + return qafx_ipv6_multicast ; + case qSAFI_MPLS_VPN: + return qafx_ipv6_mpls_vpn ; + default: + break ; + } ; + break ; + + default: + break ; + } ; + + zabort("invalid qAFI or qSAFI") ; +} ; |