in fboss/agent/state/AclEntry.cpp [432:548]
void AclEntryFields::checkFollyDynamic(const folly::dynamic& aclEntryJson) {
// check src ip and dst ip are of the same type
if (aclEntryJson.find(kSrcIp) != aclEntryJson.items().end() &&
aclEntryJson.find(kDstIp) != aclEntryJson.items().end()) {
auto src = IPAddress::createNetwork(aclEntryJson[kSrcIp].asString());
auto dst = IPAddress::createNetwork(aclEntryJson[kDstIp].asString());
if (src.first.isV4() != dst.first.isV4()) {
throw FbossError(
"Unmatched ACL IP versions ",
aclEntryJson[kSrcIp].asString(),
" vs ",
aclEntryJson[kDstIp].asString(),
"; source and destination IPs must be of the same type");
}
}
// check lookupClass is valid
if (aclEntryJson.find(kLookupClass) != aclEntryJson.items().end()) {
cfg::AclLookupClass lookupClass;
if (!TEnumTraits<cfg::AclLookupClass>::findValue(
aclEntryJson[kLookupClass].asString().c_str(), &lookupClass)) {
throw FbossError(
"Unsupported ACL Lookup Class option ",
aclEntryJson[kLookupClass].asString());
}
}
// check lookupClassL2 is valid
if (aclEntryJson.find(kLookupClassL2) != aclEntryJson.items().end()) {
cfg::AclLookupClass lookupClassL2;
if (!TEnumTraits<cfg::AclLookupClass>::findValue(
aclEntryJson[kLookupClassL2].asString().c_str(), &lookupClassL2)) {
throw FbossError(
"Unsupported ACL Lookup ClassL2 option ",
aclEntryJson[kLookupClassL2].asString());
}
}
// check lookupClassNeighbor is valid
if (aclEntryJson.find(kLookupClassNeighbor) != aclEntryJson.items().end()) {
cfg::AclLookupClass lookupClassNeighbor;
if (!TEnumTraits<cfg::AclLookupClass>::findValue(
aclEntryJson[kLookupClassNeighbor].asString().c_str(),
&lookupClassNeighbor)) {
throw FbossError(
"Unsupported ACL LookupClassNeighbor option ",
aclEntryJson[kLookupClassNeighbor].asString());
}
}
// check lookupClassRoute is valid
if (aclEntryJson.find(kLookupClassRoute) != aclEntryJson.items().end()) {
cfg::AclLookupClass lookupClassRoute;
if (!TEnumTraits<cfg::AclLookupClass>::findValue(
aclEntryJson[kLookupClassRoute].asString().c_str(),
&lookupClassRoute)) {
throw FbossError(
"Unsupported ACL LookupClassRoute option ",
aclEntryJson[kLookupClassRoute].asString());
}
}
// check ipFrag is valid
if (aclEntryJson.find(kIpFrag) != aclEntryJson.items().end()) {
cfg::IpFragMatch ipFrag;
if (!TEnumTraits<cfg::IpFragMatch>::findValue(
aclEntryJson[kIpFrag].asString().c_str(), &ipFrag)) {
throw FbossError(
"Unsupported ACL IP fragmentation option ",
aclEntryJson[kIpFrag].asString());
}
}
// check action is valid
cfg::AclActionType aclActionType;
if (!TEnumTraits<cfg::AclActionType>::findValue(
aclEntryJson[kActionType].asString().c_str(), &aclActionType)) {
throw FbossError(
"Unsupported ACL action ", aclEntryJson[kActionType].asString());
}
// check icmp type exists when icmp code exist
if (aclEntryJson.find(kIcmpCode) != aclEntryJson.items().end() &&
aclEntryJson.find(kIcmpType) == aclEntryJson.items().end()) {
throw FbossError("icmp type must be set when icmp code is set");
}
// the value of icmp type must be 0~255
if (aclEntryJson.find(kIcmpType) != aclEntryJson.items().end() &&
(aclEntryJson[kIcmpType].asInt() < 0 ||
aclEntryJson[kIcmpType].asInt() > kMaxIcmpType)) {
throw FbossError(
"icmp type value must be between 0 and ", std::to_string(kMaxIcmpType));
}
// the value of icmp code must be 0~255
if (aclEntryJson.find(kIcmpCode) != aclEntryJson.items().end() &&
(aclEntryJson[kIcmpCode].asInt() < 0 ||
aclEntryJson[kIcmpCode].asInt() > kMaxIcmpCode)) {
throw FbossError(
"icmp code value must be between 0 and ", std::to_string(kMaxIcmpCode));
}
// check the "proto" is either "icmp" or "icmpv6" when icmptype is set
if (aclEntryJson.find(kIcmpType) != aclEntryJson.items().end() &&
(aclEntryJson.find(kProto) == aclEntryJson.items().end() ||
!(aclEntryJson[kProto] == kProtoIcmp ||
aclEntryJson[kProto] == kProtoIcmpv6))) {
throw FbossError(
"proto must be either icmp or icmpv6 ", "if icmp type is set");
}
if (aclEntryJson.find(kL4SrcPort) != aclEntryJson.items().end() &&
(aclEntryJson[kL4SrcPort].asInt() < 0 ||
aclEntryJson[kL4SrcPort].asInt() > kMaxL4Port)) {
throw FbossError(
"L4 source port must be between 0 and ", std::to_string(kMaxL4Port));
}
if (aclEntryJson.find(kL4DstPort) != aclEntryJson.items().end() &&
(aclEntryJson[kL4DstPort].asInt() < 0 ||
aclEntryJson[kL4DstPort].asInt() > kMaxL4Port)) {
throw FbossError(
"L4 destination port must be between 0 and ",
std::to_string(kMaxL4Port));
}
}