]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_vxlan.c
pimd: initial infrastructure to maintain VxLAN SG database
[mirror_frr.git] / pimd / pim_vxlan.c
CommitLineData
b583b035
AK
1/* PIM support for VxLAN BUM flooding
2 *
3 * Copyright (C) 2019 Cumulus Networks, Inc.
4 *
5 * This file is part of FRR.
6 *
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 */
21
22#include <zebra.h>
23
24#include <hash.h>
25#include <jhash.h>
26#include <log.h>
27#include <prefix.h>
28#include <vrf.h>
29
30#include "pimd.h"
31#include "pim_iface.h"
32#include "pim_memory.h"
33#include "pim_oil.h"
34#include "pim_register.h"
35#include "pim_str.h"
36#include "pim_upstream.h"
37#include "pim_ifchannel.h"
38#include "pim_nht.h"
39#include "pim_zebra.h"
40#include "pim_vxlan.h"
41
42
43/************************** vxlan SG cache management ************************/
44static unsigned int pim_vxlan_sg_hash_key_make(void *p)
45{
46 struct pim_vxlan_sg *vxlan_sg = p;
47
48 return (jhash_2words(vxlan_sg->sg.src.s_addr,
49 vxlan_sg->sg.grp.s_addr, 0));
50}
51
52static bool pim_vxlan_sg_hash_eq(const void *p1, const void *p2)
53{
54 const struct pim_vxlan_sg *sg1 = p1;
55 const struct pim_vxlan_sg *sg2 = p2;
56
57 return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr)
58 && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
59}
60
61static struct pim_vxlan_sg *pim_vxlan_sg_new(struct pim_instance *pim,
62 struct prefix_sg *sg)
63{
64 struct pim_vxlan_sg *vxlan_sg;
65
66 vxlan_sg = XCALLOC(MTYPE_PIM_VXLAN_SG, sizeof(*vxlan_sg));
67
68 vxlan_sg->pim = pim;
69 vxlan_sg->sg = *sg;
70 pim_str_sg_set(sg, vxlan_sg->sg_str);
71
72 if (PIM_DEBUG_VXLAN)
73 zlog_debug("vxlan SG %s alloc", vxlan_sg->sg_str);
74
75 vxlan_sg = hash_get(pim->vxlan.sg_hash, vxlan_sg, hash_alloc_intern);
76
77 return vxlan_sg;
78}
79
80struct pim_vxlan_sg *pim_vxlan_sg_find(struct pim_instance *pim,
81 struct prefix_sg *sg)
82{
83 struct pim_vxlan_sg lookup;
84
85 lookup.sg = *sg;
86 return hash_lookup(pim->vxlan.sg_hash, &lookup);
87}
88
89struct pim_vxlan_sg *pim_vxlan_sg_add(struct pim_instance *pim,
90 struct prefix_sg *sg)
91{
92 struct pim_vxlan_sg *vxlan_sg;
93
94 vxlan_sg = pim_vxlan_sg_find(pim, sg);
95 if (vxlan_sg)
96 return vxlan_sg;
97
98 vxlan_sg = pim_vxlan_sg_new(pim, sg);
99
100 return vxlan_sg;
101}
102
103void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg)
104{
105 struct pim_vxlan_sg *vxlan_sg;
106
107 vxlan_sg = pim_vxlan_sg_find(pim, sg);
108 if (!vxlan_sg)
109 return;
110
111 hash_release(vxlan_sg->pim->vxlan.sg_hash, vxlan_sg);
112
113 if (PIM_DEBUG_VXLAN)
114 zlog_debug("vxlan SG %s free", vxlan_sg->sg_str);
115
116 XFREE(MTYPE_PIM_VXLAN_SG, vxlan_sg);
117}
118
119void pim_vxlan_init(struct pim_instance *pim)
120{
121 char hash_name[64];
122
123 snprintf(hash_name, sizeof(hash_name),
124 "PIM %s vxlan SG hash", pim->vrf->name);
125 pim->vxlan.sg_hash = hash_create(pim_vxlan_sg_hash_key_make,
126 pim_vxlan_sg_hash_eq, hash_name);
127}
128
129void pim_vxlan_exit(struct pim_instance *pim)
130{
131 if (pim->vxlan.sg_hash) {
132 hash_clean(pim->vxlan.sg_hash, NULL);
133 hash_free(pim->vxlan.sg_hash);
134 pim->vxlan.sg_hash = NULL;
135 }
136}