Commit e5cd6fe3 authored by Octavian Purdila's avatar Octavian Purdila Committed by David S. Miller

llc: add support for LLC_OPT_PKTINFO

Signed-off-by: default avatarOctavian Purdila <opurdila@ixiacom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bf9ae538
...@@ -36,6 +36,7 @@ enum llc_sockopts { ...@@ -36,6 +36,7 @@ enum llc_sockopts {
LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */ LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */
LLC_OPT_TX_WIN, /* tx window size. */ LLC_OPT_TX_WIN, /* tx window size. */
LLC_OPT_RX_WIN, /* rx window size. */ LLC_OPT_RX_WIN, /* rx window size. */
LLC_OPT_PKTINFO, /* ancillary packet information. */
LLC_OPT_MAX LLC_OPT_MAX
}; };
...@@ -70,6 +71,12 @@ enum llc_sockopts { ...@@ -70,6 +71,12 @@ enum llc_sockopts {
#define LLC_SAP_RM 0xD4 /* Resource Management */ #define LLC_SAP_RM 0xD4 /* Resource Management */
#define LLC_SAP_GLOBAL 0xFF /* Global SAP. */ #define LLC_SAP_GLOBAL 0xFF /* Global SAP. */
struct llc_pktinfo {
int lpi_ifindex;
unsigned char lpi_sap;
unsigned char lpi_mac[IFHWADDRLEN];
};
#ifdef __KERNEL__ #ifdef __KERNEL__
#define LLC_SAP_DYN_START 0xC0 #define LLC_SAP_DYN_START 0xC0
#define LLC_SAP_DYN_STOP 0xDE #define LLC_SAP_DYN_STOP 0xDE
......
...@@ -76,6 +76,7 @@ struct llc_sock { ...@@ -76,6 +76,7 @@ struct llc_sock {
u32 rx_pdu_hdr; /* used for saving header of last pdu u32 rx_pdu_hdr; /* used for saving header of last pdu
received and caused sending FRMR. received and caused sending FRMR.
Used for resending FRMR */ Used for resending FRMR */
u32 cmsg_flags;
}; };
static inline struct llc_sock *llc_sk(const struct sock *sk) static inline struct llc_sock *llc_sk(const struct sock *sk)
......
...@@ -47,6 +47,10 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout); ...@@ -47,6 +47,10 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout);
#define dprintk(args...) #define dprintk(args...)
#endif #endif
/* Maybe we'll add some more in the future. */
#define LLC_CMSG_PKTINFO 1
/** /**
* llc_ui_next_link_no - return the next unused link number for a sap * llc_ui_next_link_no - return the next unused link number for a sap
* @sap: Address of sap to get link number from. * @sap: Address of sap to get link number from.
...@@ -591,6 +595,20 @@ static int llc_wait_data(struct sock *sk, long timeo) ...@@ -591,6 +595,20 @@ static int llc_wait_data(struct sock *sk, long timeo)
return rc; return rc;
} }
static void llc_cmsg_rcv(struct msghdr *msg, struct sk_buff *skb)
{
struct llc_sock *llc = llc_sk(skb->sk);
if (llc->cmsg_flags & LLC_CMSG_PKTINFO) {
struct llc_pktinfo info;
info.lpi_ifindex = llc_sk(skb->sk)->dev->ifindex;
llc_pdu_decode_dsap(skb, &info.lpi_sap);
llc_pdu_decode_da(skb, info.lpi_mac);
put_cmsg(msg, SOL_LLC, LLC_OPT_PKTINFO, sizeof(info), &info);
}
}
/** /**
* llc_ui_accept - accept a new incoming connection. * llc_ui_accept - accept a new incoming connection.
* @sock: Socket which connections arrive on. * @sock: Socket which connections arrive on.
...@@ -812,6 +830,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -812,6 +830,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
msg->msg_namelen = sizeof(*uaddr); msg->msg_namelen = sizeof(*uaddr);
} }
if (llc_sk(sk)->cmsg_flags)
llc_cmsg_rcv(msg, skb);
goto out; goto out;
} }
...@@ -1030,6 +1050,12 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, ...@@ -1030,6 +1050,12 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
goto out; goto out;
llc->rw = opt; llc->rw = opt;
break; break;
case LLC_OPT_PKTINFO:
if (opt)
llc->cmsg_flags |= LLC_CMSG_PKTINFO;
else
llc->cmsg_flags &= ~LLC_CMSG_PKTINFO;
break;
default: default:
rc = -ENOPROTOOPT; rc = -ENOPROTOOPT;
goto out; goto out;
...@@ -1083,6 +1109,9 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname, ...@@ -1083,6 +1109,9 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
val = llc->k; break; val = llc->k; break;
case LLC_OPT_RX_WIN: case LLC_OPT_RX_WIN:
val = llc->rw; break; val = llc->rw; break;
case LLC_OPT_PKTINFO:
val = (llc->cmsg_flags & LLC_CMSG_PKTINFO) != 0;
break;
default: default:
rc = -ENOPROTOOPT; rc = -ENOPROTOOPT;
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment