From 5c0ea75421471b9e49b3241ca176e595a7d57616 Mon Sep 17 00:00:00 2001 From: Roy Date: Thu, 5 Mar 2026 23:07:43 +0000 Subject: [PATCH] Support acl_pre_ingress_vlan_table in Lucius. --- dataplane/saiserver/acl.go | 8 ++++-- dataplane/saiserver/acl_test.go | 50 +++++++++++++++++++++++++++++++-- dataplane/saiserver/tunnel.go | 27 ++++++++++++------ 3 files changed, 72 insertions(+), 13 deletions(-) diff --git a/dataplane/saiserver/acl.go b/dataplane/saiserver/acl.go index 217b8c102..e8eb0275d 100644 --- a/dataplane/saiserver/acl.go +++ b/dataplane/saiserver/acl.go @@ -440,9 +440,6 @@ func (a *acl) createAclEntryFields(req *saipb.CreateAclEntryRequest, id uint64, } } } - if len(aReq.EntryDesc.GetFlow().Fields) == 0 { - return nil, status.Error(codes.InvalidArgument, "either no fields or not unsupports fields in entry req") - } return aReq, nil } @@ -534,6 +531,11 @@ func (a *acl) CreateAclEntry(ctx context.Context, req *saipb.CreateAclEntryReque fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_VLAN_TAG). WithValue(binary.BigEndian.AppendUint16(nil, uint16(req.GetActionSetOuterVlanId().GetUint())))).Build()) } + if req.ActionSetOuterVlanPri != nil { + aReq.Actions = append(aReq.Actions, + fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_VLAN_PRIORITY). + WithValue([]byte{byte(req.GetActionSetOuterVlanPri().GetUint())})).Build()) + } if req.ActionSetTc != nil { aReq.Actions = append(aReq.Actions, fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_QOS). diff --git a/dataplane/saiserver/acl_test.go b/dataplane/saiserver/acl_test.go index 3fc4a31e2..2e15858d1 100644 --- a/dataplane/saiserver/acl_test.go +++ b/dataplane/saiserver/acl_test.go @@ -46,11 +46,57 @@ func TestCreateAclEntry(t *testing.T) { wantErr: "FailedPrecondition", req: &saipb.CreateAclEntryRequest{}, }, { - desc: "no fields", - wantErr: "InvalidArgument", + desc: "no fields", req: &saipb.CreateAclEntryRequest{ TableId: proto.Uint64(2), }, + want: &fwdpb.TableEntryAddRequest{ + ContextId: &fwdpb.ContextId{Id: "foo"}, + TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: "1"}}, + EntryDesc: &fwdpb.EntryDesc{ + Entry: &fwdpb.EntryDesc_Flow{ + Flow: &fwdpb.FlowEntryDesc{ + Id: 2, + Priority: math.MaxUint32, + }, + }, + }, + }, + }, { + desc: "action set outer vlan pri", + req: &saipb.CreateAclEntryRequest{ + TableId: proto.Uint64(2), + ActionSetOuterVlanPri: &saipb.AclActionData{ + Parameter: &saipb.AclActionData_Uint{Uint: 5}, + }, + }, + want: &fwdpb.TableEntryAddRequest{ + ContextId: &fwdpb.ContextId{Id: "foo"}, + TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: "1"}}, + EntryDesc: &fwdpb.EntryDesc{ + Entry: &fwdpb.EntryDesc_Flow{ + Flow: &fwdpb.FlowEntryDesc{ + Id: 2, + Priority: math.MaxUint32, + }, + }, + }, + Actions: []*fwdpb.ActionDesc{{ + ActionType: fwdpb.ActionType_ACTION_TYPE_UPDATE, + Action: &fwdpb.ActionDesc_Update{ + Update: &fwdpb.UpdateActionDesc{ + Type: fwdpb.UpdateType_UPDATE_TYPE_SET, + FieldId: &fwdpb.PacketFieldId{ + Field: &fwdpb.PacketField{ + FieldNum: fwdpb.PacketFieldNum_PACKET_FIELD_NUM_VLAN_PRIORITY, + }, + }, + Field: &fwdpb.PacketFieldId{Field: &fwdpb.PacketField{}}, + Value: []byte{5}, + }, + }, + }}, + }, }, { desc: "all fields", req: &saipb.CreateAclEntryRequest{ diff --git a/dataplane/saiserver/tunnel.go b/dataplane/saiserver/tunnel.go index ea085a850..bf1d75153 100644 --- a/dataplane/saiserver/tunnel.go +++ b/dataplane/saiserver/tunnel.go @@ -114,6 +114,17 @@ var ( ipV6AnyMask = make([]byte, 16) ) +func maskBytes(ip, mask []byte) []byte { + if len(ip) != len(mask) { + return ip + } + out := make([]byte, len(ip)) + for i := 0; i < len(ip); i++ { + out[i] = ip[i] & mask[i] + } + return out +} + func termFieldsFromReq(req *saipb.CreateTunnelTermTableEntryRequest) ([]*fwdpb.PacketFieldMaskedBytes, fwdpb.PacketHeaderId, error) { fields := []*fwdpb.PacketFieldMaskedBytes{} @@ -151,23 +162,23 @@ func termFieldsFromReq(req *saipb.CreateTunnelTermTableEntryRequest) ([]*fwdpb.P switch req.GetType() { case saipb.TunnelTermTableEntryType_TUNNEL_TERM_TABLE_ENTRY_TYPE_P2P: // src IP, dst IP fields = append(fields, - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(srcIP, exactMask).Build(), - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(dstIP, exactMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(maskBytes(srcIP, exactMask), exactMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(maskBytes(dstIP, exactMask), exactMask).Build(), ) case saipb.TunnelTermTableEntryType_TUNNEL_TERM_TABLE_ENTRY_TYPE_P2MP: // src IP, dst IP & mask fields = append(fields, - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(srcIP, exactMask).Build(), - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(dstIP, dstIPMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(maskBytes(srcIP, exactMask), exactMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(maskBytes(dstIP, dstIPMask), dstIPMask).Build(), ) case saipb.TunnelTermTableEntryType_TUNNEL_TERM_TABLE_ENTRY_TYPE_MP2P: // src IP & mask, dst IP fields = append(fields, - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(srcIP, srcIPMask).Build(), - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(dstIP, exactMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(maskBytes(srcIP, srcIPMask), srcIPMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(maskBytes(dstIP, exactMask), exactMask).Build(), ) case saipb.TunnelTermTableEntryType_TUNNEL_TERM_TABLE_ENTRY_TYPE_MP2MP: // src IP & mask, dst IP &mask fields = append(fields, - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(srcIP, srcIPMask).Build(), - fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(srcIP, dstIPMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(maskBytes(srcIP, srcIPMask), srcIPMask).Build(), + fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(maskBytes(dstIP, dstIPMask), dstIPMask).Build(), ) default: return nil, fwdpb.PacketHeaderId_PACKET_HEADER_ID_UNSPECIFIED, status.Errorf(codes.InvalidArgument, "invalid tunnel type: %v", req.GetType())