Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions dataplane/saiserver/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,10 @@ func (r *route) CreateRouteEntry(ctx context.Context, req *saipb.CreateRouteEntr
fib = FIBV4Table
}

if req.PacketAction == nil {
Comment thread
sonikajindal marked this conversation as resolved.
req.PacketAction = saipb.PacketAction_PACKET_ACTION_FORWARD.Enum()
}

entry := fwdconfig.TableEntryAddRequest(r.dataplane.ID(), fib).AppendEntry(fwdconfig.EntryDesc(
fwdconfig.PrefixEntry(
fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_VRF).WithUint64(req.GetEntry().GetVrId()),
Expand Down Expand Up @@ -635,6 +639,129 @@ func (r *route) CreateRouteEntry(ctx context.Context, req *saipb.CreateRouteEntr
return &saipb.CreateRouteEntryResponse{}, nil
}

func (r *route) SetRouteEntryAttribute(ctx context.Context, req *saipb.SetRouteEntryAttributeRequest) (*saipb.SetRouteEntryAttributeResponse, error) {
resp := &saipb.GetRouteEntryAttributeResponse{
Attr: &saipb.RouteEntryAttribute{},
}
pBytes, err := proto.Marshal(req.GetEntry())
if err != nil {
return nil, err
}
if err := r.mgr.PopulateAllAttributes(string(pBytes), resp.Attr); err != nil {
return nil, err
}
// The request only has one attribute, so find the one that is set.
// Only these three attributes are supported.
packetAction := resp.Attr.GetPacketAction()
if req.PacketAction != nil {
packetAction = req.GetPacketAction()
}
nextHopID := resp.Attr.GetNextHopId()
if req.NextHopId != nil {
nextHopID = req.GetNextHopId()
}
metaData := resp.Attr.MetaData
if req.MetaData != nil {
metaData = req.MetaData
}

fib := FIBV6Table
if len(req.GetEntry().GetDestination().GetAddr()) == 4 {
fib = FIBV4Table
}

entry := fwdconfig.TableEntryAddRequest(r.dataplane.ID(), fib).AppendEntry(fwdconfig.EntryDesc(
Comment thread
sonikajindal marked this conversation as resolved.
fwdconfig.PrefixEntry(
fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_VRF).WithUint64(req.GetEntry().GetVrId()),
fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(
req.GetEntry().GetDestination().GetAddr(),
req.GetEntry().GetDestination().GetMask(),
),
),
))

forward := true
if packetAction == saipb.PacketAction_PACKET_ACTION_DROP ||
packetAction == saipb.PacketAction_PACKET_ACTION_TRAP ||
packetAction == saipb.PacketAction_PACKET_ACTION_DENY {
forward = false
}
nextType := r.mgr.GetType(fmt.Sprint(nextHopID))

actions := []fwdconfig.ActionDescBuilder{}

// If the packet action is drop, then next hop is optional.
if forward {
actions = append(actions, fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{1}))
switch nextType {
case saipb.ObjectType_OBJECT_TYPE_NEXT_HOP:
actions = append(actions,
fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_NEXT_HOP_ID).WithUint64Value(nextHopID),
fwdconfig.LookupAction(NHTable),
)
case saipb.ObjectType_OBJECT_TYPE_NEXT_HOP_GROUP:
actions = append(actions,
fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_NEXT_HOP_GROUP_ID).WithUint64Value(nextHopID),
fwdconfig.LookupAction(NHGTable),
)
case saipb.ObjectType_OBJECT_TYPE_ROUTER_INTERFACE:
actions = append(actions,
// Set the next hop IP in the packet's metadata.
fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_COPY, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_NEXT_HOP_IP).WithFieldSrc(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST),
// Set the output iface.
fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_OUTPUT_IFACE).WithUint64Value(nextHopID),
)
case saipb.ObjectType_OBJECT_TYPE_PORT:
attrReq := &saipb.GetSwitchAttributeRequest{
Oid: req.GetEntry().GetSwitchId(),
AttrType: []saipb.SwitchAttr{saipb.SwitchAttr_SWITCH_ATTR_CPU_PORT},
}
resp := &saipb.GetSwitchAttributeResponse{}
if err := r.mgr.PopulateAttributes(attrReq, resp); err != nil {
return nil, err
}
if nextHopID == *resp.Attr.CpuPort {
_, err := r.dataplane.TableEntryAdd(ctx, fwdconfig.TableEntryAddRequest(r.dataplane.ID(), trapTableID).
AppendEntry(
fwdconfig.EntryDesc(fwdconfig.FlowEntry(
fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(
req.GetEntry().GetDestination().GetAddr(),
req.GetEntry().GetDestination().GetMask()),
fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_VRF).WithUint64(req.GetEntry().GetVrId()))),
fwdconfig.TransmitAction(fmt.Sprint(nextHopID)).WithImmediate(true)).
Build())
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to add next IP2ME route: %v", nextType)
}
return &saipb.SetRouteEntryAttributeResponse{}, nil
}
actions = append(actions,
// Set the next hop IP in the packet's metadata.
fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_COPY, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_NEXT_HOP_IP).WithFieldSrc(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST),
// Set the output port.
fwdconfig.TransmitAction(fmt.Sprint(nextHopID)),
)
default:
return nil, status.Errorf(codes.InvalidArgument, "unknown next hop type: %v", nextType)
}
} else {
actions = append(actions, fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{0}))
}
if metaData != nil {
actions = append(actions, fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ATTRIBUTE_32).
WithFieldIDInstance(routeDstMeta).WithValue(binary.BigEndian.AppendUint32(nil, *metaData)))
}
entry.AppendActions(actions...)

route := entry.Build()
_, err = r.dataplane.TableEntryAdd(ctx, route)
if err != nil {
return nil, err
}

return &saipb.SetRouteEntryAttributeResponse{}, nil
}

func (r *route) CreateRouteEntries(ctx context.Context, re *saipb.CreateRouteEntriesRequest) (*saipb.CreateRouteEntriesResponse, error) {
var errs errlist.List
resp := &saipb.CreateRouteEntriesResponse{}
Expand Down
21 changes: 20 additions & 1 deletion dataplane/standalone/sai/route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,26 @@ sai_status_t l_remove_route_entries(uint32_t object_count, const sai_route_entry

sai_status_t l_set_route_entries_attribute(uint32_t object_count, const sai_route_entry_t *route_entry, const sai_attribute_t *attr_list, sai_bulk_op_error_mode_t mode, sai_status_t *object_statuses) {
LOG(INFO) << "Func: " << __PRETTY_FUNCTION__;
return SAI_STATUS_NOT_IMPLEMENTED;
sai_status_t status;
sai_status_t overall_status = SAI_STATUS_SUCCESS;
bool error = false;

for (uint32_t i = 0; i < object_count; i++) {
object_statuses[i] = SAI_STATUS_NOT_EXECUTED;
if (false == error)
{
status = l_set_route_entry_attribute(&route_entry[i], &attr_list[i]);
object_statuses[i] = status;
if (status != SAI_STATUS_SUCCESS) {
overall_status = SAI_STATUS_FAILURE;
if (mode == SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR) {
error = true;
}
}
}
}

return overall_status;
}

sai_status_t l_get_route_entries_attribute(uint32_t object_count, const sai_route_entry_t *route_entry, const uint32_t *attr_count, sai_attribute_t **attr_list, sai_bulk_op_error_mode_t mode, sai_status_t *object_statuses) {
Expand Down
Loading