net/hsr/hsr_forward.c
Source file repositories/reference/linux-study-clean/net/hsr/hsr_forward.c
File Facts
- System
- Linux kernel
- Corpus path
net/hsr/hsr_forward.c- Extension
.c- Size
- 21140 bytes
- Lines
- 763
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
hsr_forward.hlinux/types.hlinux/skbuff.hlinux/etherdevice.hlinux/if_vlan.hhsr_main.hhsr_framereg.h
Detected Declarations
struct hsr_nodefunction thesefunction is_proxy_supervision_framefunction prp_set_lan_idfunction hsr_set_path_idfunction hsr_deliver_masterfunction hsr_xmitfunction prp_drop_framefunction hsr_drop_framefunction is_unicast_ether_addrfunction hsr_forward_dofunction hsr_for_each_portfunction check_local_destfunction handle_std_framefunction hsr_fill_frame_infofunction prp_fill_frame_infofunction fill_frame_infofunction hsr_forward_skb
Annotated Snippet
if (frame->skb_prp) {
/* trim the skb by len - HSR_HLEN to exclude RCT */
skb_trim(frame->skb_prp,
frame->skb_prp->len - HSR_HLEN);
frame->skb_std =
__pskb_copy(frame->skb_prp,
skb_headroom(frame->skb_prp),
GFP_ATOMIC);
if (!frame->skb_std)
return NULL;
} else {
/* Unexpected */
WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n",
__FILE__, __LINE__, port->dev->name);
return NULL;
}
}
return skb_clone(frame->skb_std, GFP_ATOMIC);
}
static void prp_set_lan_id(struct prp_rct *trailer,
struct hsr_port *port)
{
int lane_id;
if (port->type == HSR_PT_SLAVE_A)
lane_id = 0;
else
lane_id = 1;
/* Add net_id in the upper 3 bits of lane_id */
lane_id |= port->hsr->net_id;
set_prp_lan_id(trailer, lane_id);
}
/* Tailroom for PRP rct should have been created before calling this */
static struct sk_buff *prp_fill_rct(struct sk_buff *skb,
struct hsr_frame_info *frame,
struct hsr_port *port)
{
struct prp_rct *trailer;
int min_size = ETH_ZLEN;
int lsdu_size;
if (!skb)
return skb;
if (frame->is_vlan)
min_size = VLAN_ETH_ZLEN;
if (skb_put_padto(skb, min_size))
return NULL;
trailer = (struct prp_rct *)skb_put(skb, HSR_HLEN);
lsdu_size = skb->len - 14;
if (frame->is_vlan)
lsdu_size -= 4;
prp_set_lan_id(trailer, port);
set_prp_LSDU_size(trailer, lsdu_size);
trailer->sequence_nr = htons(frame->sequence_nr);
trailer->PRP_suffix = htons(ETH_P_PRP);
skb->protocol = eth_hdr(skb)->h_proto;
return skb;
}
static void hsr_set_path_id(struct hsr_frame_info *frame,
struct hsr_ethhdr *hsr_ethhdr,
struct hsr_port *port)
{
int path_id;
if (port->hsr->prot_version) {
if (port->type == HSR_PT_SLAVE_A)
path_id = 0;
else
path_id = 1;
} else {
if (frame->is_supervision)
path_id = 0xf;
else
path_id = 1;
}
set_hsr_tag_path(&hsr_ethhdr->hsr_tag, path_id);
}
static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
struct hsr_frame_info *frame,
Annotation
- Immediate include surface: `hsr_forward.h`, `linux/types.h`, `linux/skbuff.h`, `linux/etherdevice.h`, `linux/if_vlan.h`, `hsr_main.h`, `hsr_framereg.h`.
- Detected declarations: `struct hsr_node`, `function these`, `function is_proxy_supervision_frame`, `function prp_set_lan_id`, `function hsr_set_path_id`, `function hsr_deliver_master`, `function hsr_xmit`, `function prp_drop_frame`, `function hsr_drop_frame`, `function is_unicast_ether_addr`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.