diff options
-rw-r--r-- | include/linux/llc.h | 7 | ||||
-rw-r--r-- | include/net/llc_conn.h | 1 | ||||
-rw-r--r-- | net/llc/af_llc.c | 29 |
3 files changed, 37 insertions, 0 deletions
diff --git a/include/linux/llc.h b/include/linux/llc.h index 7733585603f1..ad7074ba81af 100644 --- a/include/linux/llc.h +++ b/include/linux/llc.h | |||
@@ -36,6 +36,7 @@ enum llc_sockopts { | |||
36 | LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */ | 36 | LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */ |
37 | LLC_OPT_TX_WIN, /* tx window size. */ | 37 | LLC_OPT_TX_WIN, /* tx window size. */ |
38 | LLC_OPT_RX_WIN, /* rx window size. */ | 38 | LLC_OPT_RX_WIN, /* rx window size. */ |
39 | LLC_OPT_PKTINFO, /* ancillary packet information. */ | ||
39 | LLC_OPT_MAX | 40 | LLC_OPT_MAX |
40 | }; | 41 | }; |
41 | 42 | ||
@@ -70,6 +71,12 @@ enum llc_sockopts { | |||
70 | #define LLC_SAP_RM 0xD4 /* Resource Management */ | 71 | #define LLC_SAP_RM 0xD4 /* Resource Management */ |
71 | #define LLC_SAP_GLOBAL 0xFF /* Global SAP. */ | 72 | #define LLC_SAP_GLOBAL 0xFF /* Global SAP. */ |
72 | 73 | ||
74 | struct llc_pktinfo { | ||
75 | int lpi_ifindex; | ||
76 | unsigned char lpi_sap; | ||
77 | unsigned char lpi_mac[IFHWADDRLEN]; | ||
78 | }; | ||
79 | |||
73 | #ifdef __KERNEL__ | 80 | #ifdef __KERNEL__ |
74 | #define LLC_SAP_DYN_START 0xC0 | 81 | #define LLC_SAP_DYN_START 0xC0 |
75 | #define LLC_SAP_DYN_STOP 0xDE | 82 | #define LLC_SAP_DYN_STOP 0xDE |
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index e2374e34989f..fe982fd94c4a 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h | |||
@@ -76,6 +76,7 @@ struct llc_sock { | |||
76 | u32 rx_pdu_hdr; /* used for saving header of last pdu | 76 | u32 rx_pdu_hdr; /* used for saving header of last pdu |
77 | received and caused sending FRMR. | 77 | received and caused sending FRMR. |
78 | Used for resending FRMR */ | 78 | Used for resending FRMR */ |
79 | u32 cmsg_flags; | ||
79 | }; | 80 | }; |
80 | 81 | ||
81 | static inline struct llc_sock *llc_sk(const struct sock *sk) | 82 | static inline struct llc_sock *llc_sk(const struct sock *sk) |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 3a66546cad06..ac691fe08076 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -47,6 +47,10 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout); | |||
47 | #define dprintk(args...) | 47 | #define dprintk(args...) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | /* Maybe we'll add some more in the future. */ | ||
51 | #define LLC_CMSG_PKTINFO 1 | ||
52 | |||
53 | |||
50 | /** | 54 | /** |
51 | * llc_ui_next_link_no - return the next unused link number for a sap | 55 | * llc_ui_next_link_no - return the next unused link number for a sap |
52 | * @sap: Address of sap to get link number from. | 56 | * @sap: Address of sap to get link number from. |
@@ -591,6 +595,20 @@ static int llc_wait_data(struct sock *sk, long timeo) | |||
591 | return rc; | 595 | return rc; |
592 | } | 596 | } |
593 | 597 | ||
598 | static void llc_cmsg_rcv(struct msghdr *msg, struct sk_buff *skb) | ||
599 | { | ||
600 | struct llc_sock *llc = llc_sk(skb->sk); | ||
601 | |||
602 | if (llc->cmsg_flags & LLC_CMSG_PKTINFO) { | ||
603 | struct llc_pktinfo info; | ||
604 | |||
605 | info.lpi_ifindex = llc_sk(skb->sk)->dev->ifindex; | ||
606 | llc_pdu_decode_dsap(skb, &info.lpi_sap); | ||
607 | llc_pdu_decode_da(skb, info.lpi_mac); | ||
608 | put_cmsg(msg, SOL_LLC, LLC_OPT_PKTINFO, sizeof(info), &info); | ||
609 | } | ||
610 | } | ||
611 | |||
594 | /** | 612 | /** |
595 | * llc_ui_accept - accept a new incoming connection. | 613 | * llc_ui_accept - accept a new incoming connection. |
596 | * @sock: Socket which connections arrive on. | 614 | * @sock: Socket which connections arrive on. |
@@ -812,6 +830,8 @@ copy_uaddr: | |||
812 | memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); | 830 | memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); |
813 | msg->msg_namelen = sizeof(*uaddr); | 831 | msg->msg_namelen = sizeof(*uaddr); |
814 | } | 832 | } |
833 | if (llc_sk(sk)->cmsg_flags) | ||
834 | llc_cmsg_rcv(msg, skb); | ||
815 | goto out; | 835 | goto out; |
816 | } | 836 | } |
817 | 837 | ||
@@ -1030,6 +1050,12 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, | |||
1030 | goto out; | 1050 | goto out; |
1031 | llc->rw = opt; | 1051 | llc->rw = opt; |
1032 | break; | 1052 | break; |
1053 | case LLC_OPT_PKTINFO: | ||
1054 | if (opt) | ||
1055 | llc->cmsg_flags |= LLC_CMSG_PKTINFO; | ||
1056 | else | ||
1057 | llc->cmsg_flags &= ~LLC_CMSG_PKTINFO; | ||
1058 | break; | ||
1033 | default: | 1059 | default: |
1034 | rc = -ENOPROTOOPT; | 1060 | rc = -ENOPROTOOPT; |
1035 | goto out; | 1061 | goto out; |
@@ -1083,6 +1109,9 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname, | |||
1083 | val = llc->k; break; | 1109 | val = llc->k; break; |
1084 | case LLC_OPT_RX_WIN: | 1110 | case LLC_OPT_RX_WIN: |
1085 | val = llc->rw; break; | 1111 | val = llc->rw; break; |
1112 | case LLC_OPT_PKTINFO: | ||
1113 | val = (llc->cmsg_flags & LLC_CMSG_PKTINFO) != 0; | ||
1114 | break; | ||
1086 | default: | 1115 | default: |
1087 | rc = -ENOPROTOOPT; | 1116 | rc = -ENOPROTOOPT; |
1088 | goto out; | 1117 | goto out; |