Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include <ksync/ksync_index.h>
7 : #include "vrouter/ksync/mirror_ksync.h"
8 : #include "vrouter/ksync/nexthop_ksync.h"
9 : #include "vrouter/ksync/ksync_init.h"
10 : #include <ksync/ksync_sock.h>
11 : #include "vr_mirror.h"
12 :
13 0 : MirrorKSyncEntry::MirrorKSyncEntry(MirrorKSyncObject *obj,
14 : const MirrorKSyncEntry *entry,
15 0 : uint32_t index) :
16 0 : KSyncNetlinkDBEntry(index), ksync_obj_(obj), vrf_id_(entry->vrf_id_),
17 0 : sip_(entry->sip_), sport_(entry->sport_), dip_(entry->dip_),
18 0 : dport_(entry->dport_), analyzer_name_(entry->analyzer_name_),
19 0 : mirror_flag_(entry->mirror_flag_), vni_(entry->vni_),
20 0 : nic_assisted_mirroring_(entry->nic_assisted_mirroring_),
21 0 : nic_assisted_mirroring_vlan_(entry->nic_assisted_mirroring_vlan_),
22 0 : mirror_index_(entry->mirror_index_) {
23 0 : }
24 :
25 0 : MirrorKSyncEntry::MirrorKSyncEntry(MirrorKSyncObject *obj,
26 : const uint32_t vrf_id, IpAddress dip,
27 0 : uint16_t dport) :
28 0 : KSyncNetlinkDBEntry(kInvalidIndex), ksync_obj_(obj), vrf_id_(vrf_id),
29 0 : dip_(dip), dport_(dport) {
30 0 : }
31 :
32 0 : MirrorKSyncEntry::MirrorKSyncEntry(MirrorKSyncObject *obj,
33 0 : const MirrorEntry *mirror_entry) :
34 0 : KSyncNetlinkDBEntry(kInvalidIndex), ksync_obj_(obj),
35 0 : vrf_id_(mirror_entry->vrf_id()), sip_(*mirror_entry->GetSip()),
36 0 : sport_(mirror_entry->GetSPort()), dip_(*mirror_entry->GetDip()),
37 0 : dport_(mirror_entry->GetDPort()), nh_(NULL),
38 0 : analyzer_name_(mirror_entry->GetAnalyzerName()),
39 0 : mirror_flag_(mirror_entry->GetMirrorFlag()), vni_(mirror_entry->GetVni()),
40 0 : nic_assisted_mirroring_(mirror_entry->nic_assisted_mirroring()),
41 0 : nic_assisted_mirroring_vlan_(mirror_entry->nic_assisted_mirroring_vlan()),
42 0 : mirror_index_(mirror_entry->mirror_index()) {
43 0 : }
44 :
45 0 : MirrorKSyncEntry::MirrorKSyncEntry(MirrorKSyncObject *obj,
46 0 : std::string &analyzer_name) :
47 0 : ksync_obj_(obj), analyzer_name_(analyzer_name),
48 0 : mirror_index_(MirrorTable::kInvalidIndex) {
49 0 : }
50 :
51 0 : MirrorKSyncEntry::~MirrorKSyncEntry() {
52 0 : }
53 :
54 0 : KSyncDBObject *MirrorKSyncEntry::GetObject() const {
55 0 : return ksync_obj_;
56 : }
57 :
58 0 : bool MirrorKSyncEntry::IsLess(const KSyncEntry &rhs) const {
59 0 : const MirrorKSyncEntry &entry = static_cast<const MirrorKSyncEntry &>(rhs);
60 0 : return (analyzer_name_ < entry.analyzer_name_);
61 : }
62 :
63 0 : std::string MirrorKSyncEntry::ToString() const {
64 0 : std::stringstream s;
65 :
66 0 : s << "Mirror Entry : " << dip_.to_string() << ":" << dport_;
67 : const VrfEntry* vrf =
68 0 : ksync_obj_->ksync()->agent()->vrf_table()->FindVrfFromId(vrf_id_);
69 0 : if (vrf) {
70 0 : s << " Vrf : " << vrf->GetName();
71 : }
72 0 : return s.str();
73 0 : }
74 :
75 0 : bool MirrorKSyncEntry::Sync(DBEntry *e) {
76 0 : bool ret = false;
77 0 : const MirrorEntry *mirror = static_cast<MirrorEntry *>(e);
78 : // ignore nh refernce if it is nic assisted.
79 : // and return early.
80 0 : if (nic_assisted_mirroring_ != mirror->nic_assisted_mirroring()) {
81 0 : nic_assisted_mirroring_ = mirror->nic_assisted_mirroring();
82 0 : ret = true;
83 : }
84 :
85 0 : if (mirror->nic_assisted_mirroring()) {
86 0 : nh_ = NULL;
87 0 : if (nic_assisted_mirroring_vlan_ !=
88 0 : mirror->nic_assisted_mirroring_vlan()) {
89 0 : nic_assisted_mirroring_vlan_ =
90 0 : mirror->nic_assisted_mirroring_vlan();
91 0 : ret = true;
92 : }
93 0 : return ret;
94 : } else {
95 0 : nic_assisted_mirroring_vlan_ = mirror->nic_assisted_mirroring_vlan();
96 : }
97 :
98 0 : if (vni_ != mirror->GetVni()) {
99 0 : vni_ = mirror->GetVni();
100 0 : ret =true;
101 : }
102 :
103 0 : if (mirror_flag_ != mirror->GetMirrorFlag()) {
104 0 : mirror_flag_ = mirror->GetMirrorFlag();
105 0 : ret = true;
106 : }
107 :
108 0 : NHKSyncObject *nh_object = ksync_obj_->ksync()->nh_ksync_obj();
109 0 : if (mirror->GetNH() == NULL) {
110 0 : LOG(DEBUG, "nexthop in Mirror entry is null");
111 0 : assert(0);
112 : }
113 0 : NHKSyncEntry nh_entry(nh_object, mirror->GetNH());
114 0 : NHKSyncEntry *old_nh = nh();
115 :
116 0 : nh_ = nh_object->GetReference(&nh_entry);
117 0 : if (old_nh != nh()) {
118 0 : ret = true;
119 : }
120 :
121 0 : if (mirror_index_ != mirror->mirror_index()) {
122 0 : mirror_index_ = mirror->mirror_index();
123 0 : ret = true;
124 : }
125 :
126 0 : return ret;
127 0 : }
128 :
129 0 : int MirrorKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) {
130 0 : vr_mirror_req encoder;
131 : int encode_len;
132 0 : encoder.set_mirr_index(mirror_index_);
133 0 : encoder.set_h_op(op);
134 0 : encoder.set_mirr_rid(0);
135 0 : if (!nic_assisted_mirroring_) {
136 0 : NHKSyncEntry *nh_entry = nh();
137 0 : encoder.set_mirr_nhid(nh_entry->nh_id());
138 0 : encoder.set_mirr_vni(vni_);
139 0 : if (mirror_flag_ == MirrorEntryData::DynamicNH_With_JuniperHdr) {
140 0 : encoder.set_mirr_flags(VR_MIRROR_FLAG_DYNAMIC);
141 : }
142 : } else {
143 0 : encoder.set_mirr_vlan(nic_assisted_mirroring_vlan_);
144 0 : encoder.set_mirr_flags(VR_MIRROR_FLAG_HW_ASSISTED);
145 : }
146 0 : int error = 0;
147 0 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
148 0 : assert(error == 0);
149 0 : assert(encode_len <= buf_len);
150 0 : LOG(DEBUG, "Mirror index " << GetIndex());
151 0 : return encode_len;
152 0 : }
153 :
154 0 : int MirrorKSyncEntry::AddMsg(char *buf, int buf_len) {
155 0 : LOG(DEBUG, "MirrorEntry: Add");
156 0 : return Encode(sandesh_op::ADD, buf, buf_len);
157 : }
158 :
159 0 : int MirrorKSyncEntry::ChangeMsg(char *buf, int buf_len){
160 0 : return AddMsg(buf, buf_len);
161 : }
162 :
163 0 : int MirrorKSyncEntry::DeleteMsg(char *buf, int buf_len) {
164 0 : LOG(DEBUG, "MirrorEntry: Delete");
165 0 : return Encode(sandesh_op::DEL, buf, buf_len);
166 : }
167 :
168 0 : KSyncEntry *MirrorKSyncEntry::UnresolvedReference() {
169 0 : if (nic_assisted_mirroring_) {
170 0 : return NULL;
171 : }
172 :
173 0 : NHKSyncEntry *nh_entry = nh();
174 0 : if (!nh_entry->IsResolved()) {
175 0 : return nh_entry;
176 : }
177 0 : return NULL;
178 : }
179 :
180 2 : MirrorKSyncObject::MirrorKSyncObject(KSync *ksync) :
181 2 : KSyncDBObject("KSync Mirror", kMirrorIndexCount), ksync_(ksync) {
182 2 : }
183 :
184 4 : MirrorKSyncObject::~MirrorKSyncObject() {
185 4 : }
186 :
187 2 : void MirrorKSyncObject::RegisterDBClients() {
188 2 : RegisterDb(ksync_->agent()->mirror_table());
189 2 : }
190 :
191 0 : KSyncEntry *MirrorKSyncObject::Alloc(const KSyncEntry *entry, uint32_t index) {
192 0 : const MirrorKSyncEntry *mirror_entry =
193 : static_cast<const MirrorKSyncEntry *>(entry);
194 0 : MirrorKSyncEntry *ksync = new MirrorKSyncEntry(this, mirror_entry, index);
195 0 : return static_cast<KSyncEntry *>(ksync);
196 : }
197 :
198 0 : KSyncEntry *MirrorKSyncObject::DBToKSyncEntry(const DBEntry *e) {
199 0 : const MirrorEntry *mirror_entry = static_cast<const MirrorEntry *>(e);
200 0 : MirrorKSyncEntry *ksync = new MirrorKSyncEntry(this, mirror_entry);
201 0 : return static_cast<KSyncEntry *>(ksync);
202 : }
203 :
204 0 : uint32_t MirrorKSyncObject::GetIdx(std::string analyzer_name) {
205 0 : MirrorKSyncEntry key(this, analyzer_name);
206 0 : KSyncEntry *entry = Find(&key);
207 0 : if (entry) {
208 0 : return static_cast<MirrorKSyncEntry *>(entry)->mirror_index();
209 : }
210 0 : return MirrorTable::kInvalidIndex;
211 0 : }
212 :
213 0 : void vr_mirror_req::Process(SandeshContext *context) {
214 0 : AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context);
215 0 : ioc->MirrorMsgHandler(this);
216 0 : }
|