OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
acl_entry.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <vector>
6 #include <sstream>
7 
8 #include <boost/cast.hpp>
9 
10 #include <base/util.h>
11 #include <base/logging.h>
12 #include <base/address.h>
13 
14 #include <cmn/agent_cmn.h>
15 #include <vnc_cfg_types.h>
16 #include <agent_types.h>
17 
18 #include <filter/traffic_action.h>
19 #include <filter/acl_entry_match.h>
20 #include <filter/acl_entry.h>
21 #include <filter/acl_entry_spec.h>
22 #include <filter/packet_header.h>
23 #include <filter/acl.h>
24 #include <oper/qos_config.h>
25 #include <oper/mirror_table.h>
26 #include <oper/tag.h>
27 
29 
31  // Clean up Matches
32  std::vector<AclEntryMatch *>::iterator it;
33  for (it = matches_.begin(); it != matches_.end(); it++) {
34  delete(*it);
35  }
36  matches_.clear();
37 
38  // Clean up Actions
39  ActionList::iterator ial;
40  for (ial = actions_.begin(); ial != actions_.end(); ial++) {
41  delete (*ial);
42  }
43  actions_.clear();
44 }
45 
46 void AclEntry::PopulateAclEntry(const AclEntrySpec &acl_entry_spec)
47 {
48  id_ = acl_entry_spec.id;
49  uuid_ = acl_entry_spec.rule_uuid;
50  family_ = acl_entry_spec.family;
51 
52  if (acl_entry_spec.match_tags.size()) {
53  TagsMatch *tags_match = new TagsMatch(acl_entry_spec.match_tags);
54  matches_.push_back(tags_match);
55  }
56 
57  if (acl_entry_spec.src_addr_type == AddressMatch::IP_ADDR) {
58  AddressMatch *src_addr = new AddressMatch();
59  src_addr->SetSource(true);
60  src_addr->SetIPAddress(acl_entry_spec.src_ip_list);
61  matches_.push_back(src_addr);
62  } else if (acl_entry_spec.src_addr_type == AddressMatch::NETWORK_ID){
63  AddressMatch *src_addr = new AddressMatch();
64  src_addr->SetSource(true);
65  src_addr->SetNetworkIDStr(acl_entry_spec.src_policy_id_str);
66  matches_.push_back(src_addr);
67  } else if (acl_entry_spec.src_addr_type == AddressMatch::SG) {
68  AddressMatch *src_addr = new AddressMatch();
69  src_addr->SetSource(true);
70  src_addr->SetSGId(acl_entry_spec.src_sg_id);
71  matches_.push_back(src_addr);
72  } else if (acl_entry_spec.src_addr_type == AddressMatch::TAGS) {
73  AddressMatch *src_addr = new AddressMatch();
74  src_addr->SetSource(true);
75  src_addr->SetTags(acl_entry_spec.src_tags);
76  matches_.push_back(src_addr);
77  } else if (acl_entry_spec.src_addr_type == AddressMatch::ADDRESS_GROUP) {
78  AddressMatch *src_addr = new AddressMatch();
79  src_addr->SetSource(true);
80  src_addr->SetAddressGroup(acl_entry_spec.src_ip_list,
81  acl_entry_spec.src_tags);
82  matches_.push_back(src_addr);
83  }
84 
85  if (acl_entry_spec.dst_addr_type == AddressMatch::IP_ADDR) {
86  AddressMatch *dst_addr = new AddressMatch();
87  dst_addr->SetSource(false);
88  dst_addr->SetIPAddress(acl_entry_spec.dst_ip_list);
89  matches_.push_back(dst_addr);
90  } else if (acl_entry_spec.dst_addr_type == AddressMatch::NETWORK_ID){
91  AddressMatch *dst_addr = new AddressMatch();
92  dst_addr->SetSource(false);
93  dst_addr->SetNetworkIDStr(acl_entry_spec.dst_policy_id_str);
94  matches_.push_back(dst_addr);
95  } else if (acl_entry_spec.dst_addr_type == AddressMatch::SG) {
96  AddressMatch *dst_addr = new AddressMatch();
97  dst_addr->SetSource(false);
98  dst_addr->SetSGId(acl_entry_spec.dst_sg_id);
99  matches_.push_back(dst_addr);
100  } else if (acl_entry_spec.dst_addr_type == AddressMatch::TAGS) {
101  AddressMatch *dst_addr = new AddressMatch();
102  dst_addr->SetSource(false);
103  dst_addr->SetTags(acl_entry_spec.dst_tags);
104  matches_.push_back(dst_addr);
105  } else if (acl_entry_spec.dst_addr_type == AddressMatch::ADDRESS_GROUP) {
106  AddressMatch *dst_addr = new AddressMatch();
107  dst_addr->SetSource(false);
108  dst_addr->SetAddressGroup(acl_entry_spec.dst_ip_list,
109  acl_entry_spec.dst_tags);
110  matches_.push_back(dst_addr);
111  }
112 
113  if (acl_entry_spec.protocol.size() > 0) {
114  ProtocolMatch *proto = new ProtocolMatch();
115  std::vector<RangeSpec>::const_iterator it;
116  for (it = acl_entry_spec.protocol.begin();
117  it != acl_entry_spec.protocol.end(); it++) {
118  proto->SetProtocolRange((*it).min, (*it).max);
119  }
120  matches_.push_back(proto);
121  }
122 
123  if (acl_entry_spec.dst_port.size() > 0) {
124  DstPortMatch *port = new DstPortMatch();
125  std::vector<RangeSpec>::const_iterator it;
126  for (it = acl_entry_spec.dst_port.begin();
127  it != acl_entry_spec.dst_port.end(); it++) {
128  port->SetPortRange((*it).min, (*it).max);
129  }
130  matches_.push_back(port);
131  }
132 
133  if (acl_entry_spec.src_port.size() > 0) {
134  SrcPortMatch *port = new SrcPortMatch();
135  std::vector<RangeSpec>::const_iterator it;
136  for (it = acl_entry_spec.src_port.begin();
137  it != acl_entry_spec.src_port.end(); it++) {
138  port->SetPortRange((*it).min, (*it).max);
139  }
140  matches_.push_back(port);
141  }
142 
143  if (acl_entry_spec.service_group.size() > 0) {
144  ServiceGroupMatch *service_group_match =
145  new ServiceGroupMatch(acl_entry_spec.service_group);
146  matches_.push_back(service_group_match);
147  }
148 
149  if (acl_entry_spec.action_l.size() > 0) {
150  std::vector<ActionSpec>::const_iterator it;
151  for (it = acl_entry_spec.action_l.begin();
152  it != acl_entry_spec.action_l.end(); ++it) {
153  if ((*it).ta_type == TrafficAction::SIMPLE_ACTION) {
154  SimpleAction *act = new SimpleAction((*it).simple_action);
155  actions_.push_back(act);
156  } else if ((*it).ta_type == TrafficAction::LOG_ACTION) {
157  LogAction *act = new LogAction();
158  actions_.push_back(act);
159  } else if ((*it).ta_type == TrafficAction::ALERT_ACTION) {
160  AlertAction *act = new AlertAction();
161  actions_.push_back(act);
162  } else if ((*it).ta_type == TrafficAction::MIRROR_ACTION) {
163  MirrorAction *act = new MirrorAction((*it).ma.analyzer_name,
164  (*it).ma.vrf_name,
165  (*it).ma.ip,
166  (*it).ma.port,
167  (*it).ma.encap);
168  actions_.push_back(act);
169  } else if ((*it).ta_type == TrafficAction::VRF_TRANSLATE_ACTION) {
170  VrfTranslateAction *act =
171  new VrfTranslateAction((*it).vrf_translate.vrf_name(),
172  (*it).vrf_translate.ignore_acl());
173  actions_.push_back(act);
174  } else if ((*it).ta_type == TrafficAction::QOS_ACTION) {
175  QosConfigAction *act =
176  new QosConfigAction((*it).qos_config_action.name());
177 
178  const AgentQosConfig *qos_config = Agent::GetInstance()->
179  qos_config_table()->FindByName((*it).qos_config_action.name());
180  act->set_qos_config_ref(qos_config);
181  actions_.push_back(act);
182  } else if ((*it).ta_type == TrafficAction::HBS_ACTION) {
183  HbsAction *act = new HbsAction();
184  actions_.push_back(act);
185  } else {
186  ACL_TRACE(Err, "Not supported action " + integerToString((*it).ta_type));
187  }
188  }
189  }
190 
191  if (acl_entry_spec.terminal) {
192  type_ = TERMINAL;
193  } else {
195  }
196 }
197 
199  ActionList::iterator al;
200  for (al = actions_.begin(); al != actions_.end(); al++) {
201  if ((*al)->action_type() == TrafficAction::QOS_ACTION) {
202  QosConfigAction *act = static_cast<QosConfigAction *>(*al);
203  if (act->qos_config_ref() == NULL) {
204  return false;
205  }
206  }
207  }
208  return true;
209 }
210 
212  bool ret = false;
213  ActionList::iterator al;
214  for (al = actions_.begin(); al != actions_.end(); al++) {
215  if ((*al)->action_type() == TrafficAction::QOS_ACTION) {
216  QosConfigAction *act = static_cast<QosConfigAction *>(*al);
217  const AgentQosConfig *qos_config = Agent::GetInstance()->
218  qos_config_table()->FindByName(act->name());
219  if (act->qos_config_ref() != qos_config) {
220  act->set_qos_config_ref(qos_config);
221  ret = true;
222  }
223  }
224  }
225  return ret;
226 }
227 
229  mirror_entry_ = me;
230 }
231 
233  FlowPolicyInfo *info) const
234 {
235  std::vector<AclEntryMatch *>::const_iterator it;
236  for (it = matches_.begin(); it != matches_.end(); it++) {
237  if (!((*it)->Match(&packet_header, info))) {
239  }
240  }
241  return Actions();
242 }
243 
244 void AclEntry::SetAclEntrySandeshData(AclEntrySandeshData &data) const {
245 
246  // Set match data
247  std::vector<AclEntryMatch *>::const_iterator mit;
248  for (mit = matches_.begin(); mit != matches_.end(); mit++) {
249  (*mit)->SetAclEntryMatchSandeshData(data);
250  }
251 
252  // Set action list
253  ActionList::const_iterator ait;
254  for (ait = actions_.begin(); ait != actions_.end(); ait++) {
255  (*ait)->SetActionSandeshData(data.action_l);
256  }
257 
258  // AclEntry type
259  if (type_ == TERMINAL) {
260  data.rule_type = "Terminal";
261  } else if (type_ == NON_TERMINAL) {
262  data.rule_type = "Non-Terminal";
263  } else {
264  data.rule_type = "Unknown";
265  }
266 
267  uint32_t id;
268  if (stringToInteger(id_.id_, id)) {
269  //XXX ci sanity expects integers
270  //and since we are now comparing string
271  //id are prepended with 0, and verification fails
272  //To be removed once ci scripts would be corrected.
273  data.ace_id = integerToString(id);
274  } else {
275  // AclEntry ID
276  data.ace_id = id_.id_;
277  }
278  // UUID
279  data.uuid = uuid_;
280 
281  // Setting ether_type based on AclEntry address_family
282  data.ether_type = "IPv4";
283  if (family_ == Address::INET6) {
284  data.ether_type = "IPv6";
285  }
286 }
287 
289 {
290  if (type_ == TERMINAL) {
291  return true;
292  }
293  return false;
294 }
295 
296 bool AclEntry::operator==(const AclEntry &rhs) const {
297  if (id_ != rhs.id_) {
298  return false;
299  }
300 
301  if (type_ != rhs.type_) {
302  return false;
303  }
304 
305  if (uuid_ != rhs.uuid_) {
306  return false;
307  }
308 
309  std::vector<AclEntryMatch *>::const_iterator it = matches_.begin();
310  std::vector<AclEntryMatch *>::const_iterator rhs_it = rhs.matches_.begin();
311  while (it != matches_.end() &&
312  rhs_it != rhs.matches_.end()) {
313  if (**it == **rhs_it) {
314  it++;
315  rhs_it++;
316  continue;
317  }
318  return false;
319  }
320 
321  if (it != matches_.end() || rhs_it != rhs.matches_.end()) {
322  return false;
323  }
324 
325  ActionList::const_iterator action_it = actions_.begin();
326  ActionList::const_iterator rhs_action_it = rhs.actions_.begin();
327  while (action_it != actions_.end() &&
328  rhs_action_it != rhs.actions_.end()) {
329  if (**action_it == **rhs_action_it) {
330  action_it++;
331  rhs_action_it++;
332  continue;
333  }
334  return false;
335  }
336 
337  if (action_it != actions_.end() || rhs_action_it != rhs.actions_.end()) {
338  return false;
339  }
340 
341  return true;
342 }
343 
344 void AddressMatch::SetIPAddress(const std::vector<AclAddressInfo> &list)
345 {
347  ip_list_ = list;
348 }
349 
350 void AddressMatch::SetAddressGroup(const std::vector<AclAddressInfo> &list,
351  const TagList &tags) {
353  ip_list_ = list;
354  tags_ = tags;
355 }
356 
358 {
360  policy_id_ = id;
361 }
362 
363 void AddressMatch::SetNetworkIDStr(const std::string id)
364 {
366  policy_id_s_ = id;
367 }
368 
369 void AddressMatch::SetSGId(const uint32_t sg_id)
370 {
371  addr_type_ = SG;
372  sg_id_ = sg_id;
373 }
374 
375 void AddressMatch::SetSource(const bool src)
376 {
377  src_ = src;
378 }
379 
380 bool AddressMatch::SGMatch(const SecurityGroupList *sg_l, int id) const
381 {
382  if (!sg_l) {
383  return false;
384  }
385 
386  if (id == kAny) {
387  return true;
388  }
389 
390  SecurityGroupList::const_iterator it;
391  for (it = sg_l->begin(); it != sg_l->end(); ++it) {
392  if (*it == id) return true;
393  }
394  return false;
395 }
396 
397 bool AddressMatch::SGMatch(const SecurityGroupList &sg_l, int id) const
398 {
399  if (id == kAny) {
400  return true;
401  }
402 
403  SecurityGroupList::const_iterator it;
404  for (it = sg_l.begin(); it != sg_l.end(); ++it) {
405  if (*it == id) return true;
406  }
407  return false;
408 }
409 
410 bool AddressMatch::TagsMatch(const TagList &pkt_tag_list) const {
411  TagList::const_iterator it = tags_.begin();
412  TagList::const_iterator pkt_it = pkt_tag_list.begin();
413 
414  while(it != tags_.end() && pkt_it != pkt_tag_list.end()) {
415 
416  if (*pkt_it == *it) {
417  it++;
418  pkt_it++;
419  continue;
420  }
421 
422  //Packet tag list are sorted, hence if the packet tag
423  //id is greater then there is no match and hence return
424  if (*pkt_it > *it) {
425  return false;
426  }
427 
428  if (*pkt_it < *it) {
429  pkt_it++;
430  }
431  }
432 
433  if (it == tags_.end()) {
434  return true;
435  }
436 
437  return false;
438 }
439 
440 bool AddressMatch::TagsMatchAG(const TagList &pkt_tag_list) const {
441  TagList::const_iterator it = tags_.begin();
442  TagList::const_iterator pkt_it = pkt_tag_list.begin();
443 
444  /* We are doing OR operation for address group labels
445  * If any of the tags/labels matches between endpoints,
446  * will allow traffic */
447 
448  if(it == tags_.end() || pkt_it == pkt_tag_list.end())
449  return false;
450 
451  while(it != tags_.end()) {
452  while(pkt_it != pkt_tag_list.end()) {
453  if(*pkt_it == *it) {
454  return true;
455  }
456  pkt_it++;
457  }
458  pkt_it = pkt_tag_list.begin();
459  it++;
460  }
461  return false;
462 }
463 
464 static bool SubnetMatch(const std::vector<AclAddressInfo> &list,
465  const IpAddress &data) {
466  if (list.size() == 0) {
467  return true;
468  }
469 
470  std::vector<AclAddressInfo>::const_iterator it = list.begin();
471  while (it != list.end()) {
472  IpAddress ip = it->ip_addr;
473  IpAddress mask = it->ip_mask;
474  if (data.is_v4() && ip.is_v4()) {
475  if((mask.to_v4().to_ulong() & data.to_v4().to_ulong()) ==
476  ip.to_v4().to_ulong()) {
477  return true;
478  }
479  }
480 
481  if (data.is_v6() && ip.is_v6()) {
482  const Ip6Address &ip6 = ip.to_v6();
483  const Ip6Address &data6 = data.to_v6();
484  const Ip6Address &mask6 = mask.to_v6();
485  Ip6Address::bytes_type ip6_bytes = ip6.to_bytes();
486  Ip6Address::bytes_type data6_bytes = data6.to_bytes();
487  Ip6Address::bytes_type mask6_bytes = mask6.to_bytes();
488  const uint32_t *ip6_words = (const uint32_t *)ip6_bytes.data();
489  const uint32_t *data6_words = (const uint32_t *)data6_bytes.data();
490  const uint32_t *mask6_words = (const uint32_t *)mask6_bytes.data();
491  bool matched = true;
492  for (int i = 0; i < 4; i++) {
493  if ((data6_words[i] & mask6_words[i]) != ip6_words[i]) {
494  matched = false;
495  break;
496  }
497  }
498  if (matched) {
499  return true;
500  }
501  }
502  ++it;
503  }
504 
505  return false;
506 }
507 
509  const TagList &tag_list) const {
510 
511  if (tags_.size() && TagsMatchAG(tag_list)) {
512  return true;
513  }
514 
515  if (ip_list_.size() && SubnetMatch(ip_list_, data)) {
516  return true;
517  }
518 
519  return false;
520 }
521 
522 bool AddressMatch::Match(const PacketHeader *pheader,
523  FlowPolicyInfo *info) const
524 {
525  if (policy_id_s_.compare("any") == 0) {
526  return true;
527  }
528  if (src_) {
529  if (addr_type_ == IP_ADDR) {
530  return SubnetMatch(ip_list_, pheader->src_ip);
531  } else if (addr_type_ == NETWORK_ID) {
532  if (!pheader->src_policy_id)
533  return false;
534  VnListType::iterator it =
535  pheader->src_policy_id->find(policy_id_s_);
536  if (it != pheader->src_policy_id->end()) {
537  if (info)
538  info->src_match_vn = *it;
539  return true;
540  }
541  if (info)
542  info->src_match_vn.clear();
543  return false;
544  } else if (addr_type_ == SG) {
545  return SGMatch(pheader->src_sg_id_l, sg_id_);
546  } else if (addr_type_ == TAGS) {
547  return TagsMatch(pheader->src_tags_);
548  } else if (addr_type_ == ADDRESS_GROUP) {
549  return AddressGroupMatch(pheader->src_ip, pheader->src_tags_);
550  }
551  } else {
552  if (addr_type_ == IP_ADDR) {
553  return SubnetMatch(ip_list_, pheader->dst_ip);
554  } else if (addr_type_ == NETWORK_ID) {
555  if (!pheader->dst_policy_id)
556  return false;
557  VnListType::iterator it =
558  pheader->dst_policy_id->find(policy_id_s_);
559  if (it != pheader->dst_policy_id->end()) {
560  if (info)
561  info->dst_match_vn = *it;
562  return true;
563  }
564  if (info)
565  info->dst_match_vn.clear();
566  return false;
567  } else if (addr_type_ == SG) {
568  return SGMatch(pheader->dst_sg_id_l, sg_id_);
569  } else if (addr_type_ == TAGS) {
570  return TagsMatch(pheader->dst_tags_);
571  } else if (addr_type_ == ADDRESS_GROUP) {
572  return AddressGroupMatch(pheader->dst_ip, pheader->dst_tags_);
573  }
574  }
575  return false;
576 }
577 
578 bool AddressMatch::Compare(const AclEntryMatch &rhs) const {
579  const AddressMatch &rhs_address_match =
580  static_cast<const AddressMatch &>(rhs);
581  if (addr_type_ != rhs_address_match.addr_type_) {
582  return false;
583  }
584 
585  if (src_ != rhs_address_match.src_) {
586  return false;
587  }
588 
589  if (addr_type_ == IP_ADDR) {
590  if (ip_list_ == rhs_address_match.ip_list_) {
591  return true;
592  }
593  }
594 
595  if (addr_type_ == NETWORK_ID) {
596  if (policy_id_s_ == rhs_address_match.policy_id_s_) {
597  return true;
598  }
599  }
600 
601  if (addr_type_ == SG) {
602  if (sg_id_ == rhs_address_match.sg_id_) {
603  return true;
604  }
605  }
606 
607  if (addr_type_ == TAGS) {
608  if (tags_ == rhs_address_match.tags_) {
609  return true;
610  }
611  }
612 
613  if (addr_type_ == ADDRESS_GROUP) {
614  if (tags_ == rhs_address_match.tags_ &&
615  ip_list_ == rhs_address_match.ip_list_) {
616  return true;
617  }
618  }
619 
620  return false;
621 }
622 
624  (const std::vector<AclAddressInfo> &list) {
625  std::vector<AclAddressInfo>::const_iterator it = list.begin();
626  std::stringstream ss;
627  while (it != list.end()) {
628  IpAddress ip = it->ip_addr;
629  IpAddress mask = it->ip_mask;
630  ss << ip.to_string();
631  ss << " ";
632  ss << mask.to_string();
633  ++it;
634  if (it != list.end()) {
635  ss << ", ";
636  }
637  }
638  return ss.str();
639 }
640 
641 std::string AddressMatch::BuildTags(const TagList &list) {
642 
643  TagList::const_iterator it = list.begin();
644  std::stringstream ss;
645 
646  if (it == list.end()) {
647  ss << "Empty";
648  }
649 
650  while (it != list.end()) {
651  ss << *it;
652  it++;
653  if (it != list.end()) {
654  ss << ", ";
655  }
656  }
657  return ss.str();
658 }
659 
660 void AddressMatch::SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
661 {
662 
663  std::string *str;
664  std::string *addr_type_str;
665 
666  if (src_) {
667  str = &data.src;
668  addr_type_str = &data.src_type;
669  } else {
670  str = &data.dst;
671  addr_type_str = &data.dst_type;
672  }
673 
674  if (addr_type_ == IP_ADDR) {
675  *str = BuildIpMaskList(ip_list_);
676  *addr_type_str = "ip";
677  } else if (addr_type_ == NETWORK_ID) {
678  *str = policy_id_s_;
679  *addr_type_str = "network";
680  } else if (addr_type_ == SG) {
681  std::ostringstream ss;
682  ss << sg_id_;
683  *str = ss.str();
684  *addr_type_str = "sg";
685  } else if (addr_type_ == TAGS) {
686  *addr_type_str = "tags";
687  *str = BuildTags(tags_);
688  } else if (addr_type_ == ADDRESS_GROUP) {
689  *addr_type_str = "AddressGroup";
690  std::ostringstream ss;
691  ss << BuildIpMaskList(ip_list_);
692  ss << BuildTags(tags_);
693  *str = ss.str();
694  } else {
695  *str = "Unknown Address Type";
696  *addr_type_str = "unknown";
697  }
698  return;
699 
700 }
701 
702 void ProtocolMatch::SetProtocolRange(const uint16_t min_protocol,
703  const uint16_t max_protocol)
704 {
705  Range *protocol_range = new Range(min_protocol, max_protocol);
706  protocol_ranges_.push_back(*protocol_range);
707 }
708 
709 bool ProtocolMatch::Compare(const AclEntryMatch &rhs) const {
710  const ProtocolMatch &rhs_port_match =
711  static_cast<const ProtocolMatch &>(rhs);
712  RangeSList::const_iterator it = protocol_ranges_.begin();
713  RangeSList::const_iterator rhs_it =
714  rhs_port_match.protocol_ranges_.begin();
715  while (it != protocol_ranges_.end() &&
716  rhs_it != rhs_port_match.protocol_ranges_.end()) {
717  if (*it == *rhs_it) {
718  it++;
719  rhs_it++;
720  continue;
721  }
722  return false;
723  }
724  if (it == protocol_ranges_.end() &&
725  rhs_it == rhs_port_match.protocol_ranges_.end()) {
726  return true;
727  }
728  return false;
729 }
730 
731 bool ProtocolMatch::Match(const PacketHeader *packet_header,
732  FlowPolicyInfo *info) const
733 {
734  for (RangeSList::const_iterator it = protocol_ranges_.begin();
735  it != protocol_ranges_.end(); it++) {
736  if(packet_header->protocol < (*it).min ||
737  packet_header->protocol > (*it).max) {
738  continue;
739  } else {
740  return true;
741  }
742  }
743  return false;
744 }
745 
746 void ProtocolMatch::SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
747 {
748  for (RangeSList::const_iterator it = protocol_ranges_.begin();
749  it != protocol_ranges_.end(); it++) {
750  class SandeshRange proto;
751  proto.min = (*it).min;
752  proto.max = (*it).max;
753  data.proto_l.push_back(proto);
754  }
755 }
756 
757 bool ServicePort::PortMatch(uint32_t s_port, uint32_t d_port) const {
758  if (s_port < src_port.min ||
759  s_port > src_port.max) {
760  return false;
761  }
762 
763  if (d_port < dst_port.min ||
764  d_port > dst_port.max) {
765  return false;
766  }
767 
768  return true;
769 }
770 
771 bool ServiceGroupMatch::Match(const PacketHeader *packet_header,
772  FlowPolicyInfo *info) const
773 {
774  ServicePortList::const_iterator it = service_port_list_.begin();
775  for(; it != service_port_list_.end(); it++) {
776  if (packet_header->protocol < it->protocol.min ||
777  packet_header->protocol > it->protocol.max) {
778  continue;
779  }
780 
781  if (packet_header->protocol != IPPROTO_TCP &&
782  packet_header->protocol != IPPROTO_UDP &&
783  packet_header->protocol != IPPROTO_SCTP) {
784  return true;
785  }
786 
787  if (it->PortMatch(packet_header->src_port, packet_header->dst_port)) {
788  return true;
789  }
790  }
791  return false;
792 }
793 
795  const ServiceGroupMatch &rhs_port_match =
796  static_cast<const ServiceGroupMatch &>(rhs);
797 
798  if (service_port_list_ == rhs_port_match.service_port_list_) {
799  return true;
800  }
801 
802  return false;
803 }
804 
805 void ServiceGroupMatch::SetAclEntryMatchSandeshData(AclEntrySandeshData &data) {
806  ServicePortList::const_iterator it = service_port_list_.begin();
807  for(; it != service_port_list_.end(); it++) {
808  class SandeshRange proto;
809  proto.min = it->protocol.min;
810  proto.max = it->protocol.max;
811  data.proto_l.push_back(proto);
812 
813  class SandeshRange port;
814  port.min = it->src_port.min;
815  port.max = it->src_port.max;
816  data.src_port_l.push_back(port);
817 
818  port.min = it->dst_port.min;
819  port.max = it->dst_port.max;
820  data.dst_port_l.push_back(port);
821  }
822 }
823 
824 //Used to specify match-condition between endpoints
825 //Assume match-condition says Site, in this case
826 //both source and destination should have tag of type Site
827 //and there value should match.
828 //Match condition is a list hence multiple tag type needs to be
829 //matched. For ex. if match condition says Application and Site
830 //then both source and destination should have tag of type
831 //Application and site, and there value should match
832 bool TagsMatch::Match(const PacketHeader *packet_header,
833  FlowPolicyInfo *info) const {
834  TagList::const_iterator tag_type_it = tag_list_.begin();
835  TagList::const_iterator src_tag_it = packet_header->src_tags_.begin();
836  TagList::const_iterator dst_tag_it = packet_header->dst_tags_.begin();
837 
838  while (tag_type_it != tag_list_.end() &&
839  src_tag_it != packet_header->src_tags_.end() &&
840  dst_tag_it != packet_header->dst_tags_.end()) {
841 
842  int src_tag_type = *src_tag_it >> TagEntry::kTagTypeBitShift;
843  int dst_tag_type = *dst_tag_it >> TagEntry::kTagTypeBitShift;
844 
845  //Either source or destination doesnt have given tag type
846  if (*tag_type_it < src_tag_type || *tag_type_it < dst_tag_type) {
847  return false;
848  }
849 
850  if (*tag_type_it == src_tag_type &&
851  *tag_type_it == dst_tag_type) {
852  //Tag type matches check if the value match
853  if (*src_tag_it == *dst_tag_it) {
854  //Tag match found
855  tag_type_it++;
856  src_tag_it++;
857  dst_tag_it++;
858  } else {
859  //Only Label tags are allowed to be duplicate
860  //and they are not expected in tags match
861  //As a safe check handle the same
862  if (*src_tag_it < *dst_tag_it) {
863  src_tag_it++;
864  } else {
865  dst_tag_it++;
866  }
867  }
868  continue;
869  }
870 
871  if (*tag_type_it > src_tag_type) {
872  src_tag_it++;
873  }
874 
875  if (*tag_type_it > dst_tag_type) {
876  dst_tag_it++;
877  }
878  }
879 
880  if (tag_type_it == tag_list_.end()) {
881  return true;
882  }
883 
884  return false;
885 }
886 
887 bool TagsMatch::Compare(const AclEntryMatch &rhs) const {
888  const TagsMatch &rhs_tags_match = static_cast<const TagsMatch &>(rhs);
889 
890  if (rhs_tags_match.tag_list_ == tag_list_) {
891  return true;
892  }
893 
894  return false;
895 }
896 
897 void TagsMatch::SetAclEntryMatchSandeshData(AclEntrySandeshData &data) {
898  std::stringstream str;
899  TagList::const_iterator it = tag_list_.begin();
900  for(; it != tag_list_.end(); it++) {
901  str << TagEntry::GetTypeStr(*it) << " ";
902  }
903 
904  data.set_match_condition(str.str());
905 }
906 
907 void PortMatch::SetPortRange(const uint16_t min_port, const uint16_t max_port)
908 {
909  Range *port_range = new Range(min_port, max_port);
910  port_ranges_.push_back(*port_range);
911 }
912 
913 bool PortMatch::CheckPortRanges(const uint16_t min_port,
914  const uint16_t max_port) const {
915  RangeSList::const_iterator it = port_ranges_.begin();
916  while (it != port_ranges_.end()) {
917  if ((min_port == (*it).min) && (max_port == (*it).max)) {
918  return true;
919  }
920  it++;
921  }
922  return false;
923 }
924 
925 bool PortMatch::Compare(const AclEntryMatch &rhs) const {
926  const PortMatch &rhs_port_match = static_cast<const PortMatch &>(rhs);
927  RangeSList::const_iterator it = port_ranges_.begin();
928  RangeSList::const_iterator rhs_it = rhs_port_match.port_ranges_.begin();
929  while (it != port_ranges_.end() ||
930  rhs_it != rhs_port_match.port_ranges_.end()) {
931  if (*it == *rhs_it) {
932  it++;
933  rhs_it++;
934  continue;
935  }
936  return false;
937  }
938  if (it == port_ranges_.end() &&
939  rhs_it == rhs_port_match.port_ranges_.end()) {
940  return true;
941  }
942  return false;
943 }
944 
945 bool SrcPortMatch::Match(const PacketHeader *packet_header,
946  FlowPolicyInfo *info) const
947 {
948  if (packet_header->protocol != IPPROTO_TCP &&
949  packet_header->protocol != IPPROTO_UDP) {
950  return true;
951  }
952 
953  for (RangeSList::const_iterator it = port_ranges_.begin();
954  it != port_ranges_.end(); it++) {
955  if(packet_header->src_port < (*it).min ||
956  packet_header->src_port > (*it).max) {
957  continue;
958  } else {
959  return true;
960  }
961  }
962  return false;
963 }
964 
965 void SrcPortMatch::SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
966 {
967  for (RangeSList::const_iterator it = port_ranges_.begin();
968  it != port_ranges_.end(); it++) {
969  class SandeshRange port;
970  port.min = (*it).min;
971  port.max = (*it).max;
972  data.src_port_l.push_back(port);
973  }
974 }
975 
976 
977 bool DstPortMatch::Match(const PacketHeader *packet_header,
978  FlowPolicyInfo *info) const
979 {
980  if (packet_header->protocol != IPPROTO_TCP &&
981  packet_header->protocol != IPPROTO_UDP) {
982  return true;
983  }
984 
985  for (RangeSList::const_iterator it = port_ranges_.begin();
986  it != port_ranges_.end(); it++) {
987  if(packet_header->dst_port < (*it).min ||
988  packet_header->dst_port > (*it).max) {
989  continue;
990  } else {
991  return true;
992  }
993  }
994  return false;
995 }
996 
997 void DstPortMatch::SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
998 {
999  for (RangeSList::const_iterator it = port_ranges_.begin();
1000  it != port_ranges_.end(); it++) {
1001  class SandeshRange port;
1002  port.min = (*it).min;
1003  port.max = (*it).max;
1004  data.dst_port_l.push_back(port);
1005  }
1006 }
TagList dst_tags
bool Match(const PacketHeader *packet_header, FlowPolicyInfo *info) const
Definition: acl_entry.cc:522
bool TagsMatch(const TagList &tags) const
Definition: acl_entry.cc:410
const ActionList & Actions() const
Definition: acl_entry.h:114
const SecurityGroupList * dst_sg_id_l
Definition: packet_header.h:26
std::string dst_policy_id_str
static std::string BuildTags(const TagList &list)
Definition: acl_entry.cc:641
bool IsQosConfigResolved()
Definition: acl_entry.cc:198
void SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
Definition: acl_entry.cc:997
void SetSource(bool src)
Definition: acl_entry.cc:375
void SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
Definition: acl_entry.cc:746
bool Match(const PacketHeader *packet_header, FlowPolicyInfo *info) const
Definition: acl_entry.cc:945
static const int kAny
static Agent * GetInstance()
Definition: agent.h:436
AddressMatch::AddressType dst_addr_type
void SetIPAddress(const std::vector< AclAddressInfo > &list)
Definition: acl_entry.cc:344
virtual bool Compare(const AclEntryMatch &rhs) const
Definition: acl_entry.cc:887
static const std::string & GetTypeStr(uint32_t tag_type)
void SetNetworkID(const uuid id)
Definition: acl_entry.cc:357
bool Match(const PacketHeader *packet_header, FlowPolicyInfo *info) const
Definition: acl_entry.cc:832
~AclEntry()
Definition: acl_entry.cc:30
std::list< TrafficAction * > ActionList
Definition: acl_entry.h:94
ActionList actions_
Definition: acl_entry.h:137
boost::asio::ip::address IpAddress
Definition: address.h:13
const AgentQosConfig * qos_config_ref() const
void SetSGId(const uint32_t id)
Definition: acl_entry.cc:369
bool stringToInteger(const std::string &str, NumberType &num)
Definition: string_util.h:71
std::vector< int > SecurityGroupList
Definition: agent.h:201
MirrorEntryRef mirror_entry_
Definition: acl_entry.h:138
bool operator==(const AclEntry &rhs) const
Definition: acl_entry.cc:296
void SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
Definition: acl_entry.cc:660
std::vector< RangeSpec > protocol
std::vector< AclAddressInfo > dst_ip_list
AclEntryID id_
Definition: acl_entry.h:134
const std::string & name() const
TagList dst_tags_
Definition: packet_header.h:27
std::string id_
Definition: acl_entry.h:81
std::vector< ActionSpec > action_l
const VnListType * src_policy_id
Definition: packet_header.h:20
const SecurityGroupList * src_sg_id_l
Definition: packet_header.h:21
void SetAclEntrySandeshData(AclEntrySandeshData &data) const
Definition: acl_entry.cc:244
ServiceGroupMatch::ServicePortList service_group
void SetTags(const TagList &tags)
bool AddressGroupMatch(const IpAddress &ip, const TagList &tags) const
Definition: acl_entry.cc:508
std::vector< RangeSpec > src_port
std::string src_match_vn
Definition: acl.h:29
uint16_t src_port
Definition: packet_header.h:29
static ActionList kEmptyActionList
Definition: acl_entry.h:95
#define ACL_TRACE(obj,...)
Definition: acl.h:223
std::vector< AclAddressInfo > ip_list_
virtual bool Compare(const AclEntryMatch &rhs) const
Definition: acl_entry.cc:925
boost::uuids::uuid uuid
std::string dst_match_vn
Definition: acl.h:30
const TagList & tags() const
virtual bool Compare(const AclEntryMatch &rhs) const
Definition: acl_entry.cc:578
void SetNetworkIDStr(const std::string id)
Definition: acl_entry.cc:363
TagList src_tags
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
void SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
Definition: acl_entry.cc:897
AddressType addr_type_
IpAddress src_ip
Definition: packet_header.h:19
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
RangeSList port_ranges_
const AclEntryID & id() const
Definition: acl_entry.h:120
static std::string BuildIpMaskList(const std::vector< AclAddressInfo > &list)
Definition: acl_entry.cc:624
std::string rule_uuid
AclType type_
Definition: acl_entry.h:135
bool Match(const PacketHeader *packet_header, FlowPolicyInfo *info) const
Definition: acl_entry.cc:771
void set_qos_config_ref(const AgentQosConfig *config)
RangeSList protocol_ranges_
bool Match(const PacketHeader *packet_header, FlowPolicyInfo *info) const
Definition: acl_entry.cc:977
bool PortMatch(uint32_t sport, uint32_t dport) const
Definition: acl_entry.cc:757
static bool SubnetMatch(const std::vector< AclAddressInfo > &list, const IpAddress &data)
Definition: acl_entry.cc:464
std::string policy_id_s_
bool SGMatch(const SecurityGroupList &sg_l, int id) const
Definition: acl_entry.cc:397
void SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
Definition: acl_entry.cc:965
void SetPortRange(const uint16_t min_port, const uint16_t max_port)
Definition: acl_entry.cc:907
virtual bool Compare(const AclEntryMatch &rhs) const
Definition: acl_entry.cc:709
void SetAddressGroup(const std::vector< AclAddressInfo > &list, const TagList &tags)
Definition: acl_entry.cc:350
bool ResyncQosConfigEntries()
Definition: acl_entry.cc:211
std::vector< AclEntryMatch * > matches_
Definition: acl_entry.h:136
AclEntryID id
bool TagsMatchAG(const TagList &tags) const
Definition: acl_entry.cc:440
bool Match(const PacketHeader *packet_header, FlowPolicyInfo *info) const
Definition: acl_entry.cc:731
std::string uuid_
Definition: acl_entry.h:139
void SetProtocolRange(const uint16_t min, const uint16_t max)
Definition: acl_entry.cc:702
void PopulateAclEntry(const AclEntrySpec &acl_entry_spec)
Definition: acl_entry.cc:46
boost::intrusive_ptr< MirrorEntry > MirrorEntryRef
Definition: agent.h:99
Address::Family family_
Definition: acl_entry.h:140
void SetAclEntryMatchSandeshData(AclEntrySandeshData &data)
Definition: acl_entry.cc:805
static const uint32_t kTagTypeBitShift
const VnListType * dst_policy_id
Definition: packet_header.h:25
uint16_t min
bool IsTerminal() const
Definition: acl_entry.cc:288
AddressMatch::AddressType src_addr_type
Address::Family family
uint16_t dst_port
Definition: packet_header.h:30
TagList tag_list_
ServicePortList service_port_list_
const ActionList & PacketMatch(const PacketHeader &packet_header, FlowPolicyInfo *info) const
Definition: acl_entry.cc:232
virtual bool Compare(const AclEntryMatch &rhs) const
Definition: acl_entry.cc:794
uint16_t max
IpAddress dst_ip
Definition: packet_header.h:24
std::string src_policy_id_str
std::vector< AclAddressInfo > src_ip_list
uint8_t protocol
Definition: packet_header.h:28
bool CheckPortRanges(const uint16_t min_port, const uint16_t max_port) const
Definition: acl_entry.cc:913
void set_mirror_entry(MirrorEntryRef me)
Definition: acl_entry.cc:228
TagList match_tags
TagList src_tags_
Definition: packet_header.h:22
std::vector< RangeSpec > dst_port
std::vector< int > TagList
Definition: agent.h:202