aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-12-03 21:03:28 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-12-03 21:03:28 -0500
commit2fde9901f6702ab82b5b2740fec9a7f9a80ddde4 (patch)
tree0ca92fabd4169095a50b43b8981d2a6c54f98531 /net
parentf89c2b464558a21fd3be8d578b7d13e810fb6b8a (diff)
parent3b6efee9231e12fce09c94930bfc59f66f18d662 (diff)
Merge branch 'master'
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/af_inet.c7
-rw-r--r--net/ipv4/fib_frontend.c8
-rw-r--r--net/ipv4/igmp.c5
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c29
-rw-r--r--net/ipv4/netfilter/ipt_recent.c1
-rw-r--r--net/ipv6/af_inet6.c47
-rw-r--r--net/ipv6/mcast.c5
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c29
-rw-r--r--net/sctp/socket.c10
-rw-r--r--net/sctp/transport.c3
-rw-r--r--net/sunrpc/rpc_pipe.c2
11 files changed, 100 insertions, 46 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index eaa150c33b04..d368cf249000 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -228,13 +228,14 @@ static int inet_create(struct socket *sock, int protocol)
228 unsigned char answer_flags; 228 unsigned char answer_flags;
229 char answer_no_check; 229 char answer_no_check;
230 int try_loading_module = 0; 230 int try_loading_module = 0;
231 int err = -ESOCKTNOSUPPORT; 231 int err;
232 232
233 sock->state = SS_UNCONNECTED; 233 sock->state = SS_UNCONNECTED;
234 234
235 /* Look for the requested type/protocol pair. */ 235 /* Look for the requested type/protocol pair. */
236 answer = NULL; 236 answer = NULL;
237lookup_protocol: 237lookup_protocol:
238 err = -ESOCKTNOSUPPORT;
238 rcu_read_lock(); 239 rcu_read_lock();
239 list_for_each_rcu(p, &inetsw[sock->type]) { 240 list_for_each_rcu(p, &inetsw[sock->type]) {
240 answer = list_entry(p, struct inet_protosw, list); 241 answer = list_entry(p, struct inet_protosw, list);
@@ -252,6 +253,7 @@ lookup_protocol:
252 if (IPPROTO_IP == answer->protocol) 253 if (IPPROTO_IP == answer->protocol)
253 break; 254 break;
254 } 255 }
256 err = -EPROTONOSUPPORT;
255 answer = NULL; 257 answer = NULL;
256 } 258 }
257 259
@@ -280,9 +282,6 @@ lookup_protocol:
280 err = -EPERM; 282 err = -EPERM;
281 if (answer->capability > 0 && !capable(answer->capability)) 283 if (answer->capability > 0 && !capable(answer->capability))
282 goto out_rcu_unlock; 284 goto out_rcu_unlock;
283 err = -EPROTONOSUPPORT;
284 if (!protocol)
285 goto out_rcu_unlock;
286 285
287 sock->ops = answer->ops; 286 sock->ops = answer->ops;
288 answer_prot = answer->prot; 287 answer_prot = answer->prot;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 882f88f6d13b..19b1b984d687 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -544,12 +544,16 @@ static void nl_fib_input(struct sock *sk, int len)
544 struct sk_buff *skb = NULL; 544 struct sk_buff *skb = NULL;
545 struct nlmsghdr *nlh = NULL; 545 struct nlmsghdr *nlh = NULL;
546 struct fib_result_nl *frn; 546 struct fib_result_nl *frn;
547 int err;
548 u32 pid; 547 u32 pid;
549 struct fib_table *tb; 548 struct fib_table *tb;
550 549
551 skb = skb_recv_datagram(sk, 0, 0, &err); 550 skb = skb_dequeue(&sk->sk_receive_queue);
552 nlh = (struct nlmsghdr *)skb->data; 551 nlh = (struct nlmsghdr *)skb->data;
552 if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
553 nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) {
554 kfree_skb(skb);
555 return;
556 }
553 557
554 frn = (struct fib_result_nl *) NLMSG_DATA(nlh); 558 frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
555 tb = fib_get_table(frn->tb_id_in); 559 tb = fib_get_table(frn->tb_id_in);
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index c04607b49212..4a195c724f01 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -897,7 +897,10 @@ int igmp_rcv(struct sk_buff *skb)
897 /* Is it our report looped back? */ 897 /* Is it our report looped back? */
898 if (((struct rtable*)skb->dst)->fl.iif == 0) 898 if (((struct rtable*)skb->dst)->fl.iif == 0)
899 break; 899 break;
900 igmp_heard_report(in_dev, ih->group); 900 /* don't rely on MC router hearing unicast reports */
901 if (skb->pkt_type == PACKET_MULTICAST ||
902 skb->pkt_type == PACKET_BROADCAST)
903 igmp_heard_report(in_dev, ih->group);
901 break; 904 break;
902 case IGMP_PIM: 905 case IGMP_PIM:
903#ifdef CONFIG_IP_PIMSM_V1 906#ifdef CONFIG_IP_PIMSM_V1
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 625981676776..aeb7353d4777 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -272,9 +272,9 @@ static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
272 * sCL -> sCL 272 * sCL -> sCL
273 */ 273 */
274/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ 274/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
275/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, 275/*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
276/* 276/*
277 * sSS -> sIV Might be a half-open connection. 277 * sSS -> sIG Might be a half-open connection.
278 * sSR -> sSR Might answer late resent SYN. 278 * sSR -> sSR Might answer late resent SYN.
279 * sES -> sES :-) 279 * sES -> sES :-)
280 * sFW -> sCW Normal close request answered by ACK. 280 * sFW -> sCW Normal close request answered by ACK.
@@ -917,8 +917,12 @@ static int tcp_packet(struct ip_conntrack *conntrack,
917 917
918 switch (new_state) { 918 switch (new_state) {
919 case TCP_CONNTRACK_IGNORE: 919 case TCP_CONNTRACK_IGNORE:
920 /* Either SYN in ORIGINAL 920 /* Ignored packets:
921 * or SYN/ACK in REPLY. */ 921 *
922 * a) SYN in ORIGINAL
923 * b) SYN/ACK in REPLY
924 * c) ACK in reply direction after initial SYN in original.
925 */
922 if (index == TCP_SYNACK_SET 926 if (index == TCP_SYNACK_SET
923 && conntrack->proto.tcp.last_index == TCP_SYN_SET 927 && conntrack->proto.tcp.last_index == TCP_SYN_SET
924 && conntrack->proto.tcp.last_dir != dir 928 && conntrack->proto.tcp.last_dir != dir
@@ -985,13 +989,20 @@ static int tcp_packet(struct ip_conntrack *conntrack,
985 } 989 }
986 case TCP_CONNTRACK_CLOSE: 990 case TCP_CONNTRACK_CLOSE:
987 if (index == TCP_RST_SET 991 if (index == TCP_RST_SET
988 && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) 992 && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
989 && conntrack->proto.tcp.last_index == TCP_SYN_SET 993 && conntrack->proto.tcp.last_index == TCP_SYN_SET)
994 || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
995 && conntrack->proto.tcp.last_index == TCP_ACK_SET))
990 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { 996 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
991 /* RST sent to invalid SYN we had let trough 997 /* RST sent to invalid SYN or ACK we had let trough
992 * SYN was in window then, tear down connection. 998 * at a) and c) above:
999 *
1000 * a) SYN was in window then
1001 * c) we hold a half-open connection.
1002 *
1003 * Delete our connection entry.
993 * We skip window checking, because packet might ACK 1004 * We skip window checking, because packet might ACK
994 * segments we ignored in the SYN. */ 1005 * segments we ignored. */
995 goto in_window; 1006 goto in_window;
996 } 1007 }
997 /* Just fall trough */ 1008 /* Just fall trough */
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 2d44b07688af..261cbb4d4c49 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -532,6 +532,7 @@ match(const struct sk_buff *skb,
532 } 532 }
533 if(info->seconds && info->hit_count) { 533 if(info->seconds && info->hit_count) {
534 for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { 534 for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
535 if(r_list[location].last_pkts[pkt_count] == 0) break;
535 if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++; 536 if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++;
536 } 537 }
537 if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; 538 if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c63b8ce0e1b5..d9546380fa04 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -92,10 +92,13 @@ static int inet6_create(struct socket *sock, int protocol)
92 struct proto *answer_prot; 92 struct proto *answer_prot;
93 unsigned char answer_flags; 93 unsigned char answer_flags;
94 char answer_no_check; 94 char answer_no_check;
95 int rc; 95 int try_loading_module = 0;
96 int err;
96 97
97 /* Look for the requested type/protocol pair. */ 98 /* Look for the requested type/protocol pair. */
98 answer = NULL; 99 answer = NULL;
100lookup_protocol:
101 err = -ESOCKTNOSUPPORT;
99 rcu_read_lock(); 102 rcu_read_lock();
100 list_for_each_rcu(p, &inetsw6[sock->type]) { 103 list_for_each_rcu(p, &inetsw6[sock->type]) {
101 answer = list_entry(p, struct inet_protosw, list); 104 answer = list_entry(p, struct inet_protosw, list);
@@ -113,21 +116,37 @@ static int inet6_create(struct socket *sock, int protocol)
113 if (IPPROTO_IP == answer->protocol) 116 if (IPPROTO_IP == answer->protocol)
114 break; 117 break;
115 } 118 }
119 err = -EPROTONOSUPPORT;
116 answer = NULL; 120 answer = NULL;
117 } 121 }
118 122
119 rc = -ESOCKTNOSUPPORT; 123 if (!answer) {
120 if (!answer) 124 if (try_loading_module < 2) {
121 goto out_rcu_unlock; 125 rcu_read_unlock();
122 rc = -EPERM; 126 /*
127 * Be more specific, e.g. net-pf-10-proto-132-type-1
128 * (net-pf-PF_INET6-proto-IPPROTO_SCTP-type-SOCK_STREAM)
129 */
130 if (++try_loading_module == 1)
131 request_module("net-pf-%d-proto-%d-type-%d",
132 PF_INET6, protocol, sock->type);
133 /*
134 * Fall back to generic, e.g. net-pf-10-proto-132
135 * (net-pf-PF_INET6-proto-IPPROTO_SCTP)
136 */
137 else
138 request_module("net-pf-%d-proto-%d",
139 PF_INET6, protocol);
140 goto lookup_protocol;
141 } else
142 goto out_rcu_unlock;
143 }
144
145 err = -EPERM;
123 if (answer->capability > 0 && !capable(answer->capability)) 146 if (answer->capability > 0 && !capable(answer->capability))
124 goto out_rcu_unlock; 147 goto out_rcu_unlock;
125 rc = -EPROTONOSUPPORT;
126 if (!protocol)
127 goto out_rcu_unlock;
128 148
129 sock->ops = answer->ops; 149 sock->ops = answer->ops;
130
131 answer_prot = answer->prot; 150 answer_prot = answer->prot;
132 answer_no_check = answer->no_check; 151 answer_no_check = answer->no_check;
133 answer_flags = answer->flags; 152 answer_flags = answer->flags;
@@ -135,14 +154,14 @@ static int inet6_create(struct socket *sock, int protocol)
135 154
136 BUG_TRAP(answer_prot->slab != NULL); 155 BUG_TRAP(answer_prot->slab != NULL);
137 156
138 rc = -ENOBUFS; 157 err = -ENOBUFS;
139 sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1); 158 sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
140 if (sk == NULL) 159 if (sk == NULL)
141 goto out; 160 goto out;
142 161
143 sock_init_data(sock, sk); 162 sock_init_data(sock, sk);
144 163
145 rc = 0; 164 err = 0;
146 sk->sk_no_check = answer_no_check; 165 sk->sk_no_check = answer_no_check;
147 if (INET_PROTOSW_REUSE & answer_flags) 166 if (INET_PROTOSW_REUSE & answer_flags)
148 sk->sk_reuse = 1; 167 sk->sk_reuse = 1;
@@ -202,14 +221,14 @@ static int inet6_create(struct socket *sock, int protocol)
202 sk->sk_prot->hash(sk); 221 sk->sk_prot->hash(sk);
203 } 222 }
204 if (sk->sk_prot->init) { 223 if (sk->sk_prot->init) {
205 rc = sk->sk_prot->init(sk); 224 err = sk->sk_prot->init(sk);
206 if (rc) { 225 if (err) {
207 sk_common_release(sk); 226 sk_common_release(sk);
208 goto out; 227 goto out;
209 } 228 }
210 } 229 }
211out: 230out:
212 return rc; 231 return err;
213out_rcu_unlock: 232out_rcu_unlock:
214 rcu_read_unlock(); 233 rcu_read_unlock();
215 goto out; 234 goto out;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f15e04ad026e..fd939da090c4 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1231,6 +1231,11 @@ int igmp6_event_report(struct sk_buff *skb)
1231 if (skb->pkt_type == PACKET_LOOPBACK) 1231 if (skb->pkt_type == PACKET_LOOPBACK)
1232 return 0; 1232 return 0;
1233 1233
1234 /* send our report if the MC router may not have heard this report */
1235 if (skb->pkt_type != PACKET_MULTICAST &&
1236 skb->pkt_type != PACKET_BROADCAST)
1237 return 0;
1238
1234 if (!pskb_may_pull(skb, sizeof(struct in6_addr))) 1239 if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
1235 return -EINVAL; 1240 return -EINVAL;
1236 1241
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 5a6fcf349bdf..6035633d8225 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -280,9 +280,9 @@ static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
280 * sCL -> sCL 280 * sCL -> sCL
281 */ 281 */
282/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ 282/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
283/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, 283/*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
284/* 284/*
285 * sSS -> sIV Might be a half-open connection. 285 * sSS -> sIG Might be a half-open connection.
286 * sSR -> sSR Might answer late resent SYN. 286 * sSR -> sSR Might answer late resent SYN.
287 * sES -> sES :-) 287 * sES -> sES :-)
288 * sFW -> sCW Normal close request answered by ACK. 288 * sFW -> sCW Normal close request answered by ACK.
@@ -912,8 +912,12 @@ static int tcp_packet(struct nf_conn *conntrack,
912 912
913 switch (new_state) { 913 switch (new_state) {
914 case TCP_CONNTRACK_IGNORE: 914 case TCP_CONNTRACK_IGNORE:
915 /* Either SYN in ORIGINAL 915 /* Ignored packets:
916 * or SYN/ACK in REPLY. */ 916 *
917 * a) SYN in ORIGINAL
918 * b) SYN/ACK in REPLY
919 * c) ACK in reply direction after initial SYN in original.
920 */
917 if (index == TCP_SYNACK_SET 921 if (index == TCP_SYNACK_SET
918 && conntrack->proto.tcp.last_index == TCP_SYN_SET 922 && conntrack->proto.tcp.last_index == TCP_SYN_SET
919 && conntrack->proto.tcp.last_dir != dir 923 && conntrack->proto.tcp.last_dir != dir
@@ -979,13 +983,20 @@ static int tcp_packet(struct nf_conn *conntrack,
979 } 983 }
980 case TCP_CONNTRACK_CLOSE: 984 case TCP_CONNTRACK_CLOSE:
981 if (index == TCP_RST_SET 985 if (index == TCP_RST_SET
982 && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) 986 && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
983 && conntrack->proto.tcp.last_index == TCP_SYN_SET 987 && conntrack->proto.tcp.last_index == TCP_SYN_SET)
988 || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
989 && conntrack->proto.tcp.last_index == TCP_ACK_SET))
984 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { 990 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
985 /* RST sent to invalid SYN we had let trough 991 /* RST sent to invalid SYN or ACK we had let trough
986 * SYN was in window then, tear down connection. 992 * at a) and c) above:
993 *
994 * a) SYN was in window then
995 * c) we hold a half-open connection.
996 *
997 * Delete our connection entry.
987 * We skip window checking, because packet might ACK 998 * We skip window checking, because packet might ACK
988 * segments we ignored in the SYN. */ 999 * segments we ignored. */
989 goto in_window; 1000 goto in_window;
990 } 1001 }
991 /* Just fall trough */ 1002 /* Just fall trough */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index abab81f3818f..d890dfa8818f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4743,11 +4743,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
4743 struct sk_buff *skb; 4743 struct sk_buff *skb;
4744 long timeo; 4744 long timeo;
4745 4745
4746 /* Caller is allowed not to check sk->sk_err before calling. */
4747 error = sock_error(sk);
4748 if (error)
4749 goto no_packet;
4750
4751 timeo = sock_rcvtimeo(sk, noblock); 4746 timeo = sock_rcvtimeo(sk, noblock);
4752 4747
4753 SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n", 4748 SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n",
@@ -4774,6 +4769,11 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
4774 if (skb) 4769 if (skb)
4775 return skb; 4770 return skb;
4776 4771
4772 /* Caller is allowed not to check sk->sk_err before calling. */
4773 error = sock_error(sk);
4774 if (error)
4775 goto no_packet;
4776
4777 if (sk->sk_shutdown & RCV_SHUTDOWN) 4777 if (sk->sk_shutdown & RCV_SHUTDOWN)
4778 break; 4778 break;
4779 4779
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 6bc27200e6ca..268ddaf2dc0f 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -261,7 +261,8 @@ void sctp_transport_route(struct sctp_transport *transport,
261 * association's active path for getsockname(). 261 * association's active path for getsockname().
262 */ 262 */
263 if (asoc && (transport == asoc->peer.active_path)) 263 if (asoc && (transport == asoc->peer.active_path))
264 af->to_sk_saddr(&transport->saddr, asoc->base.sk); 264 opt->pf->af->to_sk_saddr(&transport->saddr,
265 asoc->base.sk);
265 } else 266 } else
266 transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; 267 transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
267} 268}
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e3b242daf53c..c76ea221798c 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -59,7 +59,6 @@ __rpc_purge_upcall(struct inode *inode, int err)
59 struct rpc_inode *rpci = RPC_I(inode); 59 struct rpc_inode *rpci = RPC_I(inode);
60 60
61 __rpc_purge_list(rpci, &rpci->pipe, err); 61 __rpc_purge_list(rpci, &rpci->pipe, err);
62 __rpc_purge_list(rpci, &rpci->in_upcall, err);
63 rpci->pipelen = 0; 62 rpci->pipelen = 0;
64 wake_up(&rpci->waitq); 63 wake_up(&rpci->waitq);
65} 64}
@@ -119,6 +118,7 @@ rpc_close_pipes(struct inode *inode)
119 down(&inode->i_sem); 118 down(&inode->i_sem);
120 if (rpci->ops != NULL) { 119 if (rpci->ops != NULL) {
121 rpci->nreaders = 0; 120 rpci->nreaders = 0;
121 __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE);
122 __rpc_purge_upcall(inode, -EPIPE); 122 __rpc_purge_upcall(inode, -EPIPE);
123 rpci->nwriters = 0; 123 rpci->nwriters = 0;
124 if (rpci->ops->release_pipe) 124 if (rpci->ops->release_pipe)